mirror of
https://codeberg.org/angestoepselt/homepage.git
synced 2025-05-24 14:46:16 +00:00
Update formatting settings and reformat the codebase
This commit is contained in:
parent
6f52b98dcb
commit
ee64ae9493
25 changed files with 1275 additions and 1187 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
indent_style = space
|
indent_style = tab
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
|
|
|
||||||
277
.eleventy.js
277
.eleventy.js
|
|
@ -1,5 +1,4 @@
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
|
||||||
|
|
||||||
const { DateTime } = require('luxon');
|
const { DateTime } = require('luxon');
|
||||||
const pluginRss = require('@11ty/eleventy-plugin-rss');
|
const pluginRss = require('@11ty/eleventy-plugin-rss');
|
||||||
|
|
@ -11,94 +10,94 @@ const markdownItAnchor = require('markdown-it-anchor');
|
||||||
const markdownItAttrs = require('markdown-it-attrs');
|
const markdownItAttrs = require('markdown-it-attrs');
|
||||||
|
|
||||||
function hyphenize(input) {
|
function hyphenize(input) {
|
||||||
return input
|
return input
|
||||||
.replace(/[^\w- ]/, '')
|
.replace(/[^\w- ]/, '')
|
||||||
.replace(/[_ ]/, '-')
|
.replace(/[_ ]/, '-')
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = function (eleventyConfig) {
|
module.exports = function (eleventyConfig) {
|
||||||
eleventyConfig.addPlugin(pluginRss);
|
eleventyConfig.addPlugin(pluginRss);
|
||||||
eleventyConfig.addPlugin(pluginSyntaxHighlight);
|
eleventyConfig.addPlugin(pluginSyntaxHighlight);
|
||||||
eleventyConfig.addPlugin(pluginNavigation);
|
eleventyConfig.addPlugin(pluginNavigation);
|
||||||
|
|
||||||
eleventyConfig.setDataDeepMerge(true);
|
eleventyConfig.setDataDeepMerge(true);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Filters
|
// Filters
|
||||||
//
|
//
|
||||||
|
|
||||||
eleventyConfig.addFilter('readableDate', (dateObj) => {
|
eleventyConfig.addFilter('readableDate', (dateObj) => {
|
||||||
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat(
|
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat(
|
||||||
'dd LLL yyyy'
|
'dd LLL yyyy'
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
eleventyConfig.addFilter('htmlDateString', (dateObj) => {
|
eleventyConfig.addFilter('htmlDateString', (dateObj) => {
|
||||||
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd');
|
return DateTime.fromJSDate(dateObj, { zone: 'utc' }).toFormat('yyyy-LL-dd');
|
||||||
});
|
});
|
||||||
eleventyConfig.addFilter('head', (array, n) =>
|
eleventyConfig.addFilter('head', (array, n) =>
|
||||||
n < 0 ? array.slice(n) : array.slice(0, n)
|
n < 0 ? array.slice(n) : array.slice(0, n)
|
||||||
);
|
);
|
||||||
eleventyConfig.addFilter('min', (...numbers) =>
|
eleventyConfig.addFilter('min', (...numbers) =>
|
||||||
Math.min.apply(null, numbers)
|
Math.min.apply(null, numbers)
|
||||||
);
|
);
|
||||||
|
|
||||||
function filterTagList(tags) {
|
function filterTagList(tags) {
|
||||||
return (tags || []).filter(
|
return (tags || []).filter(
|
||||||
(tag) => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1
|
(tag) => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
eleventyConfig.addFilter('filterTagList', filterTagList);
|
eleventyConfig.addFilter('filterTagList', filterTagList);
|
||||||
|
|
||||||
// Build collections for the top and bottom navigation - the first one
|
// Build collections for the top and bottom navigation - the first one
|
||||||
// contains the main sites and the latter contains legal pages.
|
// contains the main sites and the latter contains legal pages.
|
||||||
eleventyConfig.addCollection('topNavigation', (collection) => {
|
eleventyConfig.addCollection('topNavigation', (collection) => {
|
||||||
return collection
|
return collection
|
||||||
.getAll()
|
.getAll()
|
||||||
.filter((item) => !(item.data.tags || []).includes('legal'));
|
.filter((item) => !(item.data.tags || []).includes('legal'));
|
||||||
});
|
});
|
||||||
eleventyConfig.addCollection('bottomNavigation', (collection) => {
|
eleventyConfig.addCollection('bottomNavigation', (collection) => {
|
||||||
return collection
|
return collection
|
||||||
.getAll()
|
.getAll()
|
||||||
.filter((item) => (item.data.tags || []).includes('legal'));
|
.filter((item) => (item.data.tags || []).includes('legal'));
|
||||||
});
|
});
|
||||||
eleventyConfig.addCollection('posts', (collection) => {
|
eleventyConfig.addCollection('posts', (collection) => {
|
||||||
return collection.getAll().filter((item) => item.data.layout === 'post');
|
return collection.getAll().filter((item) => item.data.layout === 'post');
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
// Widgets
|
// Widgets
|
||||||
//
|
//
|
||||||
|
|
||||||
eleventyConfig.addPairedShortcode(
|
eleventyConfig.addPairedShortcode(
|
||||||
'section',
|
'section',
|
||||||
(content, inverted) => `
|
(content, inverted) => `
|
||||||
<section class="page-section${inverted ? ' inverse' : ''}">
|
<section class="page-section${inverted ? ' inverse' : ''}">
|
||||||
${content}
|
${content}
|
||||||
</section>
|
</section>
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
|
|
||||||
eleventyConfig.addPairedShortcode(
|
eleventyConfig.addPairedShortcode(
|
||||||
'tabs',
|
'tabs',
|
||||||
(content) => `
|
(content) => `
|
||||||
<div class="tabs-widget">
|
<div class="tabs-widget">
|
||||||
${content}
|
${content}
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
);
|
);
|
||||||
eleventyConfig.addPairedShortcode('tab', (content, title) => {
|
eleventyConfig.addPairedShortcode('tab', (content, title) => {
|
||||||
const hyphenizedTitle = hyphenize(title);
|
const hyphenizedTitle = hyphenize(title);
|
||||||
return `
|
return `
|
||||||
<div id="${hyphenizedTitle}" class="tab">
|
<div id="${hyphenizedTitle}" class="tab">
|
||||||
${content}
|
${content}
|
||||||
</div>
|
</div>
|
||||||
<a href="#${hyphenizedTitle}" rel="tab">${title}</a>
|
<a href="#${hyphenizedTitle}" rel="tab">${title}</a>
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
eleventyConfig.addPairedShortcode('timeline', (content, stamp) => {
|
eleventyConfig.addPairedShortcode('timeline', (content, stamp) => {
|
||||||
return `
|
return `
|
||||||
<section class="timeline">
|
<section class="timeline">
|
||||||
<span class="stamp${stamp === undefined ? ' small' : ''}">
|
<span class="stamp${stamp === undefined ? ' small' : ''}">
|
||||||
${stamp || ''}
|
${stamp || ''}
|
||||||
|
|
@ -108,101 +107,101 @@ ${content}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
`;
|
`;
|
||||||
});
|
});
|
||||||
|
|
||||||
eleventyConfig.addPairedAsyncShortcode(
|
eleventyConfig.addPairedAsyncShortcode(
|
||||||
'banner',
|
'banner',
|
||||||
async (content, title, backgroundSource, backgroundAlt) => {
|
async (content, title, backgroundSource, backgroundAlt) => {
|
||||||
const backgroundMetadata = await Image(`src/images/${backgroundSource}`, {
|
const backgroundMetadata = await Image(`src/images/${backgroundSource}`, {
|
||||||
widths: [1200, 1980, 4000],
|
widths: [1200, 1980, 4000],
|
||||||
formats: ['avif', 'webp', 'jpeg'],
|
formats: ['avif', 'webp', 'jpeg'],
|
||||||
urlPath: '/assets/img',
|
urlPath: '/assets/img',
|
||||||
outputDir: './dist/assets/img',
|
outputDir: './dist/assets/img',
|
||||||
sharpAvifOptions: { quality: 40 },
|
sharpAvifOptions: { quality: 40 },
|
||||||
sharpWebpOptions: { quality: 50 },
|
sharpWebpOptions: { quality: 50 },
|
||||||
sharpJpegOptions: { quality: 65 },
|
sharpJpegOptions: { quality: 65 },
|
||||||
});
|
});
|
||||||
const backgroundHTML = Image.generateHTML(backgroundMetadata, {
|
const backgroundHTML = Image.generateHTML(backgroundMetadata, {
|
||||||
alt: backgroundAlt,
|
alt: backgroundAlt,
|
||||||
sizes: '100vw',
|
sizes: '100vw',
|
||||||
loading: 'lazy',
|
loading: 'lazy',
|
||||||
decoding: 'async',
|
decoding: 'async',
|
||||||
whitespaceMode: 'inline',
|
whitespaceMode: 'inline',
|
||||||
});
|
});
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="page-banner">
|
<div class="page-banner">
|
||||||
<div class="background">${backgroundHTML}</div>
|
<div class="background">${backgroundHTML}</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
${title ? '<div class="title">' + title + '</div>' : ''}
|
${title ? '<div class="title">' + title + '</div>' : ''}
|
||||||
${
|
${
|
||||||
// The '\n's here are required so that markdown still gets rendered in the
|
// The '\n's here are required so that markdown still gets rendered in the
|
||||||
// content block:
|
// content block:
|
||||||
content.trim() ? '<div>\n' + content + '\n</div>' : ''
|
content.trim() ? '<div>\n' + content + '\n</div>' : ''
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Templating
|
// Templating
|
||||||
//
|
//
|
||||||
|
|
||||||
eleventyConfig.addLayoutAlias('page', 'layouts/page.njk');
|
eleventyConfig.addLayoutAlias('page', 'layouts/page.njk');
|
||||||
eleventyConfig.addLayoutAlias('post', 'layouts/post.njk');
|
eleventyConfig.addLayoutAlias('post', 'layouts/post.njk');
|
||||||
|
|
||||||
let markdownLibrary = markdownIt({
|
let markdownLibrary = markdownIt({
|
||||||
html: true,
|
html: true,
|
||||||
breaks: false,
|
breaks: false,
|
||||||
linkify: true,
|
linkify: true,
|
||||||
})
|
})
|
||||||
.use(markdownItAnchor)
|
.use(markdownItAnchor)
|
||||||
.use(markdownItAttrs);
|
.use(markdownItAttrs);
|
||||||
eleventyConfig.setLibrary('md', markdownLibrary);
|
eleventyConfig.setLibrary('md', markdownLibrary);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Build settings
|
// Build settings
|
||||||
//
|
//
|
||||||
|
|
||||||
eleventyConfig.addPassthroughCopy({ 'src/assets': 'assets' });
|
eleventyConfig.addPassthroughCopy({ 'src/assets': 'assets' });
|
||||||
|
|
||||||
eleventyConfig.setBrowserSyncConfig({
|
eleventyConfig.setBrowserSyncConfig({
|
||||||
callbacks: {
|
callbacks: {
|
||||||
ready: function (err, browserSync) {
|
ready: function (err, browserSync) {
|
||||||
const content_404 = fs.readFileSync('dist/404.html');
|
const content_404 = fs.readFileSync('dist/404.html');
|
||||||
|
|
||||||
browserSync.addMiddleware('*', (req, res) => {
|
browserSync.addMiddleware('*', (req, res) => {
|
||||||
// Provides the 404 content without redirect.
|
// Provides the 404 content without redirect.
|
||||||
res.writeHead(404, { 'Content-Type': 'text/html; charset=UTF-8' });
|
res.writeHead(404, { 'Content-Type': 'text/html; charset=UTF-8' });
|
||||||
res.write(content_404);
|
res.write(content_404);
|
||||||
res.end();
|
res.end();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
ui: false,
|
ui: false,
|
||||||
ghostMode: false,
|
ghostMode: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
//
|
//
|
||||||
// Other settings
|
// Other settings
|
||||||
//
|
//
|
||||||
|
|
||||||
return {
|
return {
|
||||||
dir: {
|
dir: {
|
||||||
input: 'src/content',
|
input: 'src/content',
|
||||||
// These are all relative to the input directory so the paths get a little
|
// These are all relative to the input directory so the paths get a little
|
||||||
// weird:
|
// weird:
|
||||||
includes: '../includes',
|
includes: '../includes',
|
||||||
data: '../data',
|
data: '../data',
|
||||||
output: 'dist',
|
output: 'dist',
|
||||||
},
|
},
|
||||||
|
|
||||||
templateFormats: ['md', 'njk', 'html', 'liquid'],
|
templateFormats: ['md', 'njk', 'html', 'liquid'],
|
||||||
|
|
||||||
markdownTemplateEngine: 'njk',
|
markdownTemplateEngine: 'njk',
|
||||||
htmlTemplateEngine: 'njk',
|
htmlTemplateEngine: 'njk',
|
||||||
dataTemplateEngine: false,
|
dataTemplateEngine: false,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
11
.prettierrc
11
.prettierrc
|
|
@ -1,7 +1,8 @@
|
||||||
{
|
{
|
||||||
"arrowParens": "always",
|
"arrowParens": "always",
|
||||||
"printWidth": 80,
|
"printWidth": 80,
|
||||||
"proseWrap": "preserve",
|
"proseWrap": "preserve",
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "es5"
|
"trailingComma": "es5",
|
||||||
|
"useTabs": true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
172
flake.nix
172
flake.nix
|
|
@ -1,106 +1,106 @@
|
||||||
{
|
{
|
||||||
description = "Angestöpselt Homepage";
|
description = "Angestöpselt Homepage";
|
||||||
|
|
||||||
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
|
inputs.nixpkgs.url = "nixpkgs/nixos-unstable";
|
||||||
inputs.flake-utils.url = "github:numtide/flake-utils";
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
|
||||||
outputs = {self, nixpkgs, flake-utils }: let
|
outputs = {self, nixpkgs, flake-utils }: let
|
||||||
base = flake-utils.lib.eachDefaultSystem (system:
|
base = flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
|
||||||
nodejs = pkgs.nodejs-16_x;
|
nodejs = pkgs.nodejs-16_x;
|
||||||
|
|
||||||
nodePackages = import ./nix/default.nix { inherit pkgs system nodejs; };
|
nodePackages = import ./nix/default.nix { inherit pkgs system nodejs; };
|
||||||
nodeDependencies = nodePackages.nodeDependencies.override {
|
nodeDependencies = nodePackages.nodeDependencies.override {
|
||||||
nativeBuildInputs = with pkgs; [ pkg-config ];
|
nativeBuildInputs = with pkgs; [ pkg-config ];
|
||||||
buildInputs = with pkgs; [ vips ];
|
buildInputs = with pkgs; [ vips ];
|
||||||
dontNpmInstall = true;
|
dontNpmInstall = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
in
|
in
|
||||||
rec {
|
rec {
|
||||||
packages = {
|
packages = {
|
||||||
site = pkgs.stdenv.mkDerivation {
|
site = pkgs.stdenv.mkDerivation {
|
||||||
name = "angestoepselt-site";
|
name = "angestoepselt-site";
|
||||||
src = self;
|
src = self;
|
||||||
|
|
||||||
buildInputs = [ nodejs nodeDependencies ];
|
buildInputs = [ nodejs nodeDependencies ];
|
||||||
|
|
||||||
buildPhase = ''
|
buildPhase = ''
|
||||||
npm run build
|
npm run build
|
||||||
'';
|
'';
|
||||||
|
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
mv dist $out
|
mv dist $out
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
container = pkgs.dockerTools.buildImage {
|
container = pkgs.dockerTools.buildImage {
|
||||||
name = "angestoepselt-site-container";
|
name = "angestoepselt-site-container";
|
||||||
tag = "latest";
|
tag = "latest";
|
||||||
|
|
||||||
config = {
|
config = {
|
||||||
Cmd = [
|
Cmd = [
|
||||||
"${pkgs.caddy}/bin/caddy"
|
"${pkgs.caddy}/bin/caddy"
|
||||||
"file-server"
|
"file-server"
|
||||||
"-root" "${packages.site}"
|
"-root" "${packages.site}"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
# This package isn't actually the fully-built site, but rather a
|
# This package isn't actually the fully-built site, but rather a
|
||||||
# derivation that contains the relevant programs (with correctly set up
|
# derivation that contains the relevant programs (with correctly set up
|
||||||
# environment) to develop and build the site. It can either be used with
|
# environment) to develop and build the site. It can either be used with
|
||||||
# `nix develop` – see the repository's readme for details – or compiled
|
# `nix develop` – see the repository's readme for details – or compiled
|
||||||
# with `nix build`. The latter will output a folder which contains node
|
# with `nix build`. The latter will output a folder which contains node
|
||||||
# and npm binaries that can be used in an IDE.
|
# and npm binaries that can be used in an IDE.
|
||||||
devEnv = pkgs.symlinkJoin {
|
devEnv = pkgs.symlinkJoin {
|
||||||
name = "devEnv";
|
name = "devEnv";
|
||||||
|
|
||||||
buildInputs = [ pkgs.makeWrapper ];
|
buildInputs = [ pkgs.makeWrapper ];
|
||||||
paths = [ nodejs nodeDependencies ];
|
paths = [ nodejs nodeDependencies ];
|
||||||
|
|
||||||
postBuild = ''
|
postBuild = ''
|
||||||
wrapProgram "$out/bin/node" \
|
wrapProgram "$out/bin/node" \
|
||||||
--prefix PATH : "$out/lib/node_modules/.bin" \
|
--prefix PATH : "$out/lib/node_modules/.bin" \
|
||||||
--prefix NODE_PATH : "$out/lib/node_modules"
|
--prefix NODE_PATH : "$out/lib/node_modules"
|
||||||
'';
|
'';
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
export NODE_PATH=${nodeDependencies}/lib/node_modules
|
export NODE_PATH=${nodeDependencies}/lib/node_modules
|
||||||
export PATH="${nodeDependencies}/bin:${nodejs}/bin:${pkgs.nodePackages.npm-check-updates}/bin:$PATH"
|
export PATH="${nodeDependencies}/bin:${nodejs}/bin:${pkgs.nodePackages.npm-check-updates}/bin:$PATH"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo " To start editing content, run:"
|
echo " To start editing content, run:"
|
||||||
echo ""
|
echo ""
|
||||||
echo "npm run build:styles"
|
echo "npm run build:styles"
|
||||||
echo "npm run dev:site"
|
echo "npm run dev:site"
|
||||||
echo ""
|
echo ""
|
||||||
echo " The site will be available under http://localhost:8080/ for"
|
echo " The site will be available under http://localhost:8080/ for"
|
||||||
echo " local development and rebuilds automatically when content"
|
echo " local development and rebuilds automatically when content"
|
||||||
echo " changes."
|
echo " changes."
|
||||||
echo ""
|
echo ""
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
defaultPackage = packages.angestoepseltSite;
|
defaultPackage = packages.angestoepseltSite;
|
||||||
|
|
||||||
devShell = packages.devEnv;
|
devShell = packages.devEnv;
|
||||||
});
|
});
|
||||||
in (base // {
|
in (base // {
|
||||||
hydraJobs = rec {
|
hydraJobs = rec {
|
||||||
inherit (base.packages.x86_64-linux) site;
|
inherit (base.packages.x86_64-linux) site;
|
||||||
|
|
||||||
container = let
|
container = let
|
||||||
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
pkgs = import nixpkgs { system = "x86_64-linux"; };
|
||||||
containerFile = base.packages.x86_64-linux.container;
|
containerFile = base.packages.x86_64-linux.container;
|
||||||
in pkgs.runCommand "container" {} ''
|
in pkgs.runCommand "container" {} ''
|
||||||
mkdir -p $out/nix-support
|
mkdir -p $out/nix-support
|
||||||
ln -s ${containerFile} $out/angestoepselt-site.tar.gz
|
ln -s ${containerFile} $out/angestoepselt-site.tar.gz
|
||||||
echo "file oci $out/angestoepselt-site.tar.gz" > $out/nix-support/hydra-build-products
|
echo "file oci $out/angestoepselt-site.tar.gz" > $out/nix-support/hydra-build-products
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,21 +2,21 @@ PROJECT_DIR=$(dirname "$(dirname "$0")")
|
||||||
NIX_DIR="$PROJECT_DIR/nix"
|
NIX_DIR="$PROJECT_DIR/nix"
|
||||||
|
|
||||||
if [ -h "$PROJECT_DIR/node_modules" ]; then
|
if [ -h "$PROJECT_DIR/node_modules" ]; then
|
||||||
rm node_modules
|
rm node_modules
|
||||||
fi
|
fi
|
||||||
|
|
||||||
npm install --package-lock-only
|
npm install --package-lock-only
|
||||||
node2nix \
|
node2nix \
|
||||||
-i "$PROJECT_DIR/package.json" \
|
-i "$PROJECT_DIR/package.json" \
|
||||||
-l "$PROJECT_DIR/package-lock.json" \
|
-l "$PROJECT_DIR/package-lock.json" \
|
||||||
-o "$NIX_DIR/node-packages.nix" \
|
-o "$NIX_DIR/node-packages.nix" \
|
||||||
-c "$NIX_DIR/default.nix" \
|
-c "$NIX_DIR/default.nix" \
|
||||||
-e "$NIX_DIR/node-env.nix" \
|
-e "$NIX_DIR/node-env.nix" \
|
||||||
--development \
|
--development \
|
||||||
--include-peer-dependencies
|
--include-peer-dependencies
|
||||||
|
|
||||||
nix build -o "$PROJECT_DIR/.dev" ".#angestoepseltSiteEnv"
|
nix build -o "$PROJECT_DIR/.dev" ".#angestoepseltSiteEnv"
|
||||||
|
|
||||||
if [ ! -e "$PROJECT_DIR/node_modules" ]; then
|
if [ ! -e "$PROJECT_DIR/node_modules" ]; then
|
||||||
cd "$PROJECT_DIR"; ln -s .dev/lib/node_modules .
|
cd "$PROJECT_DIR"; ln -s .dev/lib/node_modules .
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
54
package.json
54
package.json
|
|
@ -1,29 +1,29 @@
|
||||||
{
|
{
|
||||||
"name": "angestoepselt-site",
|
"name": "angestoepselt-site",
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"description": "Angestöpselt Homepage",
|
"description": "Angestöpselt Homepage",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build:site": "eleventy",
|
"build:site": "eleventy",
|
||||||
"build:styles": "sass --style=compressed src/styles/:dist/assets/css/",
|
"build:styles": "sass --style=compressed src/styles/:dist/assets/css/",
|
||||||
"build": "npm run build:site && npm run build:styles",
|
"build": "npm run build:site && npm run build:styles",
|
||||||
"dev:site": "eleventy --serve",
|
"dev:site": "eleventy --serve",
|
||||||
"dev:styles": "sass --watch src/styles/:dist/assets/css/"
|
"dev:styles": "sass --watch src/styles/:dist/assets/css/"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.17.1"
|
"express": "^4.17.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@11ty/eleventy": "^0.12.1",
|
"@11ty/eleventy": "^0.12.1",
|
||||||
"@11ty/eleventy-img": "^1.0.0",
|
"@11ty/eleventy-img": "^1.0.0",
|
||||||
"@11ty/eleventy-navigation": "^0.3.2",
|
"@11ty/eleventy-navigation": "^0.3.2",
|
||||||
"@11ty/eleventy-plugin-rss": "^1.1.2",
|
"@11ty/eleventy-plugin-rss": "^1.1.2",
|
||||||
"@11ty/eleventy-plugin-syntaxhighlight": "^3.1.3",
|
"@11ty/eleventy-plugin-syntaxhighlight": "^3.1.3",
|
||||||
"luxon": "^2.0.2",
|
"luxon": "^2.0.2",
|
||||||
"markdown-it": "^12.2.0",
|
"markdown-it": "^12.2.0",
|
||||||
"markdown-it-anchor": "^8.4.1",
|
"markdown-it-anchor": "^8.4.1",
|
||||||
"markdown-it-attrs": "^4.1.0",
|
"markdown-it-attrs": "^4.1.0",
|
||||||
"prettier": "^2.4.1",
|
"prettier": "^2.4.1",
|
||||||
"sass": "^1.43.3"
|
"sass": "^1.43.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ eleventyExcludeFromCollections: true
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||||
{%- for page in collections.all %}
|
{%- for page in collections.all %}
|
||||||
{% set absoluteUrl %}{{ page.url | url | absoluteUrl(metadata.url) }}{% endset %}
|
{% set absoluteUrl %}{{ page.url | url | absoluteUrl(metadata.url) }}{% endset %}
|
||||||
<url>
|
<url>
|
||||||
<loc>{{ absoluteUrl }}</loc>
|
<loc>{{ absoluteUrl }}</loc>
|
||||||
<lastmod>{{ page.date | htmlDateString }}</lastmod>
|
<lastmod>{{ page.date | htmlDateString }}</lastmod>
|
||||||
</url>
|
</url>
|
||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</urlset>
|
</urlset>
|
||||||
|
|
|
||||||
|
|
@ -1,102 +1,102 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="{{ metadata.language }}">
|
<html lang="{{ metadata.language }}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>{{ title or metadata.title }}</title>
|
<title>{{ title or metadata.title }}</title>
|
||||||
|
|
||||||
<link rel="preload" href="{{ '/assets/css/base.css' | url }}" as="style">
|
<link rel="preload" href="{{ '/assets/css/base.css' | url }}" as="style">
|
||||||
{# We only bother with preloading the variable font here because chances are
|
{# We only bother with preloading the variable font here because chances are
|
||||||
that if a browser doesn't support variable fonts it won't support
|
that if a browser doesn't support variable fonts it won't support
|
||||||
preloading either:
|
preloading either:
|
||||||
https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#browser_compatibility
|
https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types/preload#browser_compatibility
|
||||||
#}
|
#}
|
||||||
<link rel="preload" href="{{ '/assets/fonts/Comfortaa-VariableFont_wght.ttf' | url }}" as="font" crossorigin="anonymous">
|
<link rel="preload" href="{{ '/assets/fonts/Comfortaa-VariableFont_wght.ttf' | url }}" as="font" crossorigin="anonymous">
|
||||||
{% for name in (extraStylesheets or []) %}
|
{% for name in (extraStylesheets or []) %}
|
||||||
<link rel="preload" href="{{ '/assets/css/' + name + '.css' | url }}" as="style">
|
<link rel="preload" href="{{ '/assets/css/' + name + '.css' | url }}" as="style">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% block headStart %}{% endblock %}
|
{% block headStart %}{% endblock %}
|
||||||
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
|
||||||
<meta name="description" content="{{ description or metadata.description }}">
|
<meta name="description" content="{{ description or metadata.description }}">
|
||||||
<link rel="alternate" href="{{ metadata.feed.path | url }}" type="application/atom+xml" title="{{ metadata.title }}">
|
<link rel="alternate" href="{{ metadata.feed.path | url }}" type="application/atom+xml" title="{{ metadata.title }}">
|
||||||
<link rel="alternate" href="{{ metadata.jsonfeed.path | url }}" type="application/json" title="{{ metadata.title }}">
|
<link rel="alternate" href="{{ metadata.jsonfeed.path | url }}" type="application/json" title="{{ metadata.title }}">
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{ '/assets/css/base.css' | url }}">
|
<link rel="stylesheet" href="{{ '/assets/css/base.css' | url }}">
|
||||||
{% for name in (extraStylesheets or []) %}
|
{% for name in (extraStylesheets or []) %}
|
||||||
<link rel="stylesheet" href="{{ '/assets/css/' + name + '.css' | url }}">
|
<link rel="stylesheet" href="{{ '/assets/css/' + name + '.css' | url }}">
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% block headEnd %}{% endblock %}
|
{% block headEnd %}{% endblock %}
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header class="site-header">
|
<header class="site-header">
|
||||||
<a class="site-logo" href="{{ '/' | url }}">{{ metadata.title }}</a>
|
<a class="site-logo" href="{{ '/' | url }}">{{ metadata.title }}</a>
|
||||||
|
|
||||||
<details class="site-mobile-navigation">
|
<details class="site-mobile-navigation">
|
||||||
<summary>Menü</summary>
|
<summary>Menü</summary>
|
||||||
<nav class="site-navigation">
|
<nav class="site-navigation">
|
||||||
<ul>
|
<ul>
|
||||||
{% for entry in collections.topNavigation | eleventyNavigation %}
|
{% for entry in collections.topNavigation | eleventyNavigation %}
|
||||||
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
||||||
<a href="{{ entry.url }}">
|
<a href="{{ entry.url }}">
|
||||||
{{ entry.title }}
|
{{ entry.title }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<nav class="site-navigation horizontal">
|
<nav class="site-navigation horizontal">
|
||||||
<ul>
|
<ul>
|
||||||
{% for entry in collections.topNavigation | eleventyNavigation %}
|
{% for entry in collections.topNavigation | eleventyNavigation %}
|
||||||
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
||||||
<a href="{{ entry.url }}">
|
<a href="{{ entry.url }}">
|
||||||
{{ entry.title }}
|
{{ entry.title }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main id="content" {% if contentClass %} class="{{ contentClass }}"{% endif %}>
|
<main id="content" {% if contentClass %} class="{{ contentClass }}"{% endif %}>
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{{ content | safe }}
|
{{ content | safe }}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<footer class="page-section footer">
|
<footer class="page-section footer">
|
||||||
<div class="page-content site-footer">
|
<div class="page-content site-footer">
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
{{ metadata.author.name }}
|
{{ metadata.author.name }}
|
||||||
{% for line in (metadata.author.address or []) %}
|
{% for line in (metadata.author.address or []) %}
|
||||||
<br />
|
<br />
|
||||||
{{ line }}
|
{{ line }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{ metadata.author.email }}
|
{{ metadata.author.email }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<nav class="site-navigation">
|
<nav class="site-navigation">
|
||||||
<ul>
|
<ul>
|
||||||
{% for entry in collections.bottomNavigation | eleventyNavigation %}
|
{% for entry in collections.bottomNavigation | eleventyNavigation %}
|
||||||
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
<li{% if entry.url == page.url %} class="active"{% endif %}>
|
||||||
<a href="{{ entry.url }}">
|
<a href="{{ entry.url }}">
|
||||||
{{ entry.title }}
|
{{ entry.title }}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
{% if useForms %}
|
{% if useForms %}
|
||||||
{% set extraStylesheets = [ "forms" ].concat(extraStylesheets or []) %}
|
{% set extraStylesheets = [ "forms" ].concat(extraStylesheets or []) %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% extends "layouts/base.njk" %}
|
{% extends "layouts/base.njk" %}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ templateClass: tmpl-post
|
||||||
{%- if nextPost or previousPost %}
|
{%- if nextPost or previousPost %}
|
||||||
<hr>
|
<hr>
|
||||||
<ul>
|
<ul>
|
||||||
{%- if nextPost %}<li>Next: <a href="{{ nextPost.url | url }}">{{ nextPost.data.title }}</a></li>{% endif %}
|
{%- if nextPost %}<li>Next: <a href="{{ nextPost.url | url }}">{{ nextPost.data.title }}</a></li>{% endif %}
|
||||||
{%- if previousPost %}<li>Previous: <a href="{{ previousPost.url | url }}">{{ previousPost.data.title }}</a></li>{% endif %}
|
{%- if previousPost %}<li>Previous: <a href="{{ previousPost.url | url }}">{{ previousPost.data.title }}</a></li>{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
|
|
|
||||||
|
|
@ -7,5 +7,5 @@
|
||||||
@include typography.root-config;
|
@include typography.root-config;
|
||||||
|
|
||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,187 +5,219 @@
|
||||||
// Actions are another module that is present on the home page. It shows a small
|
// Actions are another module that is present on the home page. It shows a small
|
||||||
// number of CTA-style buttons which lead to different parts of the site.
|
// number of CTA-style buttons which lead to different parts of the site.
|
||||||
.page-actions {
|
.page-actions {
|
||||||
padding: layout.$large-gap;
|
padding: layout.$large-gap;
|
||||||
background-color: colors.$teal-300;
|
background-color: colors.$teal-300;
|
||||||
|
|
||||||
> *:not(:last-child) {
|
> *:not(:last-child) {
|
||||||
margin-bottom: layout.$large-gap;
|
margin-bottom: layout.$large-gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
> *:first-child {
|
> *:first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
> *:last-child {
|
> *:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column-reverse;
|
||||||
margin: layout.$large-gap 0;
|
margin: layout.$large-gap 0;
|
||||||
padding: layout.$large-gap;
|
padding: layout.$large-gap;
|
||||||
background: colors.$gray-50;
|
background: colors.$gray-50;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@include colors.card-shadow;
|
@include colors.card-shadow;
|
||||||
transition: motion.$subtle background-color, motion.$subtle transform;
|
transition: motion.$subtle background-color, motion.$subtle transform;
|
||||||
|
|
||||||
> h3 {
|
> h3 {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
> svg {
|
> svg {
|
||||||
align-self: center;
|
align-self: center;
|
||||||
margin-bottom: layout.$normal-gap;
|
margin-bottom: layout.$normal-gap;
|
||||||
height: 10rem;
|
height: 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: colors.$gray-100;
|
background-color: colors.$gray-100;
|
||||||
transform: translateY(-0.5rem);
|
transform: translateY(-0.5rem);
|
||||||
|
|
||||||
> .action-icon {
|
> .action-icon {
|
||||||
@extend %action-icon-hover;
|
@extend %action-icon-hover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: layout.$breakpoint) {
|
@media screen and (min-width: layout.$breakpoint) {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(6, 1fr);
|
grid-template-columns: repeat(6, 1fr);
|
||||||
gap: layout.$large-gap;
|
gap: layout.$large-gap;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
grid-column: span 3;
|
grid-column: span 3;
|
||||||
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
&.first {
|
&.first {
|
||||||
position: relative;
|
position: relative;
|
||||||
bottom: layout.$huge-gap;
|
bottom: layout.$huge-gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.first) {
|
&:not(.first) {
|
||||||
grid-column: span 2;
|
grid-column: span 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-icon {
|
.action-icon {
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
fill: colors.$main-text;
|
fill: colors.$main-text;
|
||||||
// This seems to prevent jittering in Firefox:
|
// This seems to prevent jittering in Firefox:
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@extend %action-icon-hover;
|
@extend %action-icon-hover;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emphasis-gradient > stop {
|
.emphasis-gradient > stop {
|
||||||
stop-color: colors.$blue-500;
|
stop-color: colors.$blue-500;
|
||||||
transition: motion.$gentle stop-color;
|
transition: motion.$gentle stop-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.emphasis {
|
.emphasis {
|
||||||
transition: motion.$gentle transform;
|
transition: motion.$gentle transform;
|
||||||
|
|
||||||
&.heart-left {
|
&.heart-left {
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.heart-right {
|
&.heart-right {
|
||||||
transform-origin: top right;
|
transform-origin: top right;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.coin {
|
&.coin {
|
||||||
transform-origin: 58% 39%;
|
transform-origin: 58% 39%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%action-icon-hover {
|
%action-icon-hover {
|
||||||
.emphasis-gradient {
|
.emphasis-gradient {
|
||||||
@keyframes action-icon-emphasis-gradient-1 {
|
@keyframes action-icon-emphasis-gradient-1 {
|
||||||
0% { stop-color: colors.$blue-500; }
|
0% {
|
||||||
40% { stop-color: colors.$yellow-500; }
|
stop-color: colors.$blue-500;
|
||||||
80% { stop-color: colors.$teal-500; }
|
}
|
||||||
}
|
40% {
|
||||||
|
stop-color: colors.$yellow-500;
|
||||||
|
}
|
||||||
|
80% {
|
||||||
|
stop-color: colors.$teal-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes action-icon-emphasis-gradient-2 {
|
@keyframes action-icon-emphasis-gradient-2 {
|
||||||
0% { stop-color: colors.$blue-500; }
|
0% {
|
||||||
20% { stop-color: colors.$blue-800; }
|
stop-color: colors.$blue-500;
|
||||||
60% { stop-color: colors.$yellow-500; }
|
}
|
||||||
100% { stop-color: colors.$teal-500; }
|
20% {
|
||||||
}
|
stop-color: colors.$blue-800;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
stop-color: colors.$yellow-500;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stop-color: colors.$teal-500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@for $i from 1 through 2 {
|
@for $i from 1 through 2 {
|
||||||
> stop:nth-of-type(#{$i}) {
|
> stop:nth-of-type(#{$i}) {
|
||||||
stop-color: colors.$teal-500;
|
stop-color: colors.$teal-500;
|
||||||
animation:
|
animation: motion.$prominent
|
||||||
motion.$prominent 0s 1 normal backwards running
|
0s
|
||||||
action-icon-emphasis-gradient-#{$i};
|
1
|
||||||
}
|
normal
|
||||||
}
|
backwards
|
||||||
}
|
running
|
||||||
|
action-icon-emphasis-gradient-#{$i};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.heart-left {
|
.heart-left {
|
||||||
$final-transformation:
|
$final-transformation: translateX(-0.8rem) translateY(1.4rem) scale(1.5)
|
||||||
translateX(-0.8rem) translateY(1.4rem) scale(1.5) rotate(-25deg);
|
rotate(-25deg);
|
||||||
|
|
||||||
@keyframes action-icon-heart-left {
|
@keyframes action-icon-heart-left {
|
||||||
0% { transform: none; }
|
0% {
|
||||||
50% {
|
transform: none;
|
||||||
transform:
|
}
|
||||||
translateX(0.2rem) translateY(0.8rem) scale(1.2) rotate(-10deg);
|
50% {
|
||||||
}
|
transform: translateX(0.2rem) translateY(0.8rem) scale(1.2)
|
||||||
100% { transform: $final-transformation; }
|
rotate(-10deg);
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
|
transform: $final-transformation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transform: $final-transformation;
|
transform: $final-transformation;
|
||||||
animation:
|
animation: motion.$gentle 0s 1 normal backwards running
|
||||||
motion.$gentle 0s 1 normal backwards running action-icon-heart-left;
|
action-icon-heart-left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.heart-right {
|
.heart-right {
|
||||||
$final-transformation:
|
$final-transformation: translateX(1.4rem) translateY(-0.1rem) scale(1.6)
|
||||||
translateX(1.4rem) translateY(-0.1rem) scale(1.6) rotate(15deg);
|
rotate(15deg);
|
||||||
|
|
||||||
@keyframes action-icon-heart-right {
|
@keyframes action-icon-heart-right {
|
||||||
0% { transform: none; }
|
0% {
|
||||||
50% {
|
transform: none;
|
||||||
transform:
|
}
|
||||||
translateX(1.3rem) translateY(0.8rem) scale(1.4) rotate(30deg);
|
50% {
|
||||||
}
|
transform: translateX(1.3rem) translateY(0.8rem) scale(1.4)
|
||||||
100% { transform: $final-transformation; }
|
rotate(30deg);
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
|
transform: $final-transformation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transform: $final-transformation;
|
transform: $final-transformation;
|
||||||
animation:
|
animation: motion.$gentle 0s 1 normal backwards running
|
||||||
motion.$gentle 0s 1 normal backwards running action-icon-heart-right;
|
action-icon-heart-right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.coin {
|
.coin {
|
||||||
$final-transformation: scale(0.8);
|
$final-transformation: scale(0.8);
|
||||||
|
|
||||||
@keyframes action-icon-coin {
|
@keyframes action-icon-coin {
|
||||||
0% { transform: none; }
|
0% {
|
||||||
50% { transform: scale(1.1); }
|
transform: none;
|
||||||
100% { transform: $final-transformation; }
|
}
|
||||||
}
|
50% {
|
||||||
|
transform: scale(1.1);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: $final-transformation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
transform: $final-transformation;
|
transform: $final-transformation;
|
||||||
animation: motion.$gentle 0s 1 normal backwards running action-icon-coin;
|
animation: motion.$gentle 0s 1 normal backwards running action-icon-coin;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,56 +7,56 @@
|
||||||
// - A .background element which contains an image to render behind the text
|
// - A .background element which contains an image to render behind the text
|
||||||
// - A .content which holds the actual text.
|
// - A .content which holds the actual text.
|
||||||
.page-banner {
|
.page-banner {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 60vh;
|
min-height: 60vh;
|
||||||
background-color: colors.$blue-800;
|
background-color: colors.$blue-800;
|
||||||
|
|
||||||
> .background {
|
> .background {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
img {
|
img {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: layout.$normal-gap max(#{layout.$large-gap}, 15vw);
|
padding: layout.$normal-gap max(#{layout.$large-gap}, 15vw);
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: layout.$small-gap layout.$normal-gap;
|
padding: layout.$small-gap layout.$normal-gap;
|
||||||
font-size: typography.$subheading-size;
|
font-size: typography.$subheading-size;
|
||||||
background-color: colors.$yellow-600;
|
background-color: colors.$yellow-600;
|
||||||
|
|
||||||
> p:first-child {
|
> p:first-child {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
> p:last-child {
|
> p:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .title {
|
> .title {
|
||||||
padding: 0 layout.$normal-gap;
|
padding: 0 layout.$normal-gap;
|
||||||
line-height: 5rem;
|
line-height: 5rem;
|
||||||
font-size: typography.$title-size;
|
font-size: typography.$title-size;
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
background-color: colors.$teal-500;
|
background-color: colors.$teal-500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,91 +4,94 @@
|
||||||
@use '../lib/layout';
|
@use '../lib/layout';
|
||||||
|
|
||||||
.form-choices {
|
.form-choices {
|
||||||
@extend %narrow-content;
|
@extend %narrow-content;
|
||||||
margin-top: layout.$huge-gap;
|
margin-top: layout.$huge-gap;
|
||||||
margin-bottom: layout.$huge-gap;
|
margin-bottom: layout.$huge-gap;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
content: '\2771';
|
content: '\2771';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(:last-child) {
|
&:not(:last-child) {
|
||||||
&:before {
|
&:before {
|
||||||
top: calc(50% - #{math.div(layout.$large-gap, 2)});
|
top: calc(50% - #{math.div(layout.$large-gap, 2)});
|
||||||
}
|
}
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
margin: layout.$large-gap auto;
|
margin: layout.$large-gap auto;
|
||||||
width: 15rem;
|
width: 15rem;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
@extend %form-choice-link;
|
@extend %form-choice-link;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.narrow {
|
&.narrow {
|
||||||
margin-top: layout.$large-gap;
|
margin-top: layout.$large-gap;
|
||||||
margin-bottom: layout.$large-gap;
|
margin-bottom: layout.$large-gap;
|
||||||
|
|
||||||
> li::after {
|
> li::after {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%form-choice-link {
|
%form-choice-link {
|
||||||
padding: layout.$small-gap layout.$normal-gap;
|
padding: layout.$small-gap layout.$normal-gap;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
line-height: 2.5;
|
line-height: 2.5;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: motion.$subtle background-color, motion.$subtle box-shadow;
|
transition: motion.$subtle background-color, motion.$subtle box-shadow;
|
||||||
|
|
||||||
@keyframes form-choice-hover {
|
@keyframes form-choice-hover {
|
||||||
0% { background-position: -100% 0; }
|
0% {
|
||||||
100% { background-position: 200% 0; }
|
background-position: -100% 0;
|
||||||
}
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus-visible {
|
&:focus-visible {
|
||||||
background-color: colors.$yellow-600;
|
background-color: colors.$yellow-600;
|
||||||
background-image: linear-gradient(
|
background-image: linear-gradient(
|
||||||
-45deg,
|
-45deg,
|
||||||
transparent 0%,
|
transparent 0%,
|
||||||
#{transparentize(colors.$yellow-500, 0.6)} 50%,
|
#{transparentize(colors.$yellow-500, 0.6)} 50%,
|
||||||
transparent 100%
|
transparent 100%
|
||||||
);
|
);
|
||||||
background-size: 200% 100%;
|
background-size: 200% 100%;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
@include colors.card-shadow(colors.$yellow-500);
|
@include colors.card-shadow(colors.$yellow-500);
|
||||||
animation:
|
animation: motion.$prominent 0s 1 normal both running form-choice-hover;
|
||||||
motion.$prominent 0s 1 normal both running form-choice-hover;
|
|
||||||
|
|
||||||
> em {
|
> em {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> em {
|
> em {
|
||||||
padding-block: layout.$small-gap;
|
padding-block: layout.$small-gap;
|
||||||
font-style: inherit;
|
font-style: inherit;
|
||||||
background-color: colors.$yellow-600;
|
background-color: colors.$yellow-600;
|
||||||
transition: motion.$subtle background-color;
|
transition: motion.$subtle background-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,101 +4,101 @@
|
||||||
@use '../lib/typography';
|
@use '../lib/typography';
|
||||||
|
|
||||||
%form-item {
|
%form-item {
|
||||||
@extend %narrow-content-gutter;
|
@extend %narrow-content-gutter;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
%form-label {
|
%form-label {
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
color: colors.$blue-800;
|
color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
%base-form-input {
|
%base-form-input {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
border: 0.1rem solid colors.$blue-800;
|
border: 0.1rem solid colors.$blue-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
%form-input {
|
%form-input {
|
||||||
@extend %base-form-input;
|
@extend %base-form-input;
|
||||||
padding: layout.$small-gap;
|
padding: layout.$small-gap;
|
||||||
font: inherit;
|
font: inherit;
|
||||||
transition: motion.$subtle background-color;
|
transition: motion.$subtle background-color;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-visible,
|
&:focus-visible,
|
||||||
&:active {
|
&:active {
|
||||||
outline: none;
|
outline: none;
|
||||||
background-color: colors.$yellow-500;
|
background-color: colors.$yellow-500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-input {
|
.form-input {
|
||||||
@extend %form-item;
|
@extend %form-item;
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
@extend %form-label;
|
@extend %form-label;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
> input,
|
> input,
|
||||||
> textarea {
|
> textarea {
|
||||||
@extend %form-input;
|
@extend %form-input;
|
||||||
flex-basis: 60%;
|
flex-basis: 60%;
|
||||||
margin-left: layout.$normal-gap;
|
margin-left: layout.$normal-gap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-checkbox {
|
.form-checkbox {
|
||||||
$size: 2rem;
|
$size: 2rem;
|
||||||
$gap: layout.$small-gap;
|
$gap: layout.$small-gap;
|
||||||
|
|
||||||
@extend %form-item;
|
@extend %form-item;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|
||||||
&:hover > div {
|
&:hover > div {
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
}
|
}
|
||||||
|
|
||||||
> input {
|
> input {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
&:checked + div::before {
|
&:checked + div::before {
|
||||||
content: '\2713';
|
content: '\2713';
|
||||||
font-size: 1.8rem;
|
font-size: 1.8rem;
|
||||||
line-height: $size;
|
line-height: $size;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:focus-visible + div {
|
&:focus-visible + div {
|
||||||
background-color: colors.$yellow-600;
|
background-color: colors.$yellow-600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
@extend %base-form-input;
|
@extend %base-form-input;
|
||||||
width: $size;
|
width: $size;
|
||||||
height: $size;
|
height: $size;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
> span {
|
> span {
|
||||||
@extend %form-label;
|
@extend %form-label;
|
||||||
flex-basis: calc(60% - #{$size + $gap});
|
flex-basis: calc(60% - #{$size + $gap});
|
||||||
margin-left: $gap;
|
margin-left: $gap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-submit {
|
.form-submit {
|
||||||
@extend %form-item;
|
@extend %form-item;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
margin: layout.$huge-gap auto;
|
margin: layout.$huge-gap auto;
|
||||||
|
|
||||||
> input {
|
> input {
|
||||||
@extend %form-input;
|
@extend %form-input;
|
||||||
flex-basis: 60%;
|
flex-basis: 60%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,148 +4,151 @@
|
||||||
@use '../lib/typography';
|
@use '../lib/typography';
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: colors.$main-text;
|
color: colors.$main-text;
|
||||||
}
|
}
|
||||||
|
|
||||||
%title {
|
%title {
|
||||||
@extend %content;
|
@extend %content;
|
||||||
margin-top: layout.$huge-gap;
|
margin-top: layout.$huge-gap;
|
||||||
margin-bottom: layout.$large-gap;
|
margin-bottom: layout.$large-gap;
|
||||||
font-size: typography.$title-size;
|
font-size: typography.$title-size;
|
||||||
line-height: typography.$heading-line-height;
|
line-height: typography.$heading-line-height;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@extend %title;
|
@extend %title;
|
||||||
}
|
}
|
||||||
|
|
||||||
%heading {
|
%heading {
|
||||||
@extend %content;
|
@extend %content;
|
||||||
margin-top: layout.$large-gap;
|
margin-top: layout.$large-gap;
|
||||||
margin-bottom: layout.$large-gap;
|
margin-bottom: layout.$large-gap;
|
||||||
font-size: typography.$heading-size;
|
font-size: typography.$heading-size;
|
||||||
line-height: typography.$heading-line-height;
|
line-height: typography.$heading-line-height;
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
width: 8rem;
|
width: 8rem;
|
||||||
height: 0.3rem;
|
height: 0.3rem;
|
||||||
margin-top: 0.2rem;
|
margin-top: 0.2rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
background-color: colors.$blue-800;
|
background-color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
@extend %heading;
|
@extend %heading;
|
||||||
}
|
}
|
||||||
|
|
||||||
%subheading {
|
%subheading {
|
||||||
@extend %content-gutter;
|
@extend %content-gutter;
|
||||||
font-size: typography.$subheading-size;
|
font-size: typography.$subheading-size;
|
||||||
line-height: typography.$heading-line-height;
|
line-height: typography.$heading-line-height;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
@extend %subheading;
|
@extend %subheading;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
@extend %content-gutter;
|
@extend %content-gutter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, ol, dl {
|
ul,
|
||||||
@extend %content-gutter;
|
ol,
|
||||||
|
dl {
|
||||||
|
@extend %content-gutter;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
margin: layout.$small-gap 0;
|
margin: layout.$small-gap 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
dt {
|
dt {
|
||||||
margin: layout.$normal-gap 0;
|
margin: layout.$normal-gap 0;
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
color: colors.$blue-800;
|
color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
|
|
||||||
dd {
|
dd {
|
||||||
margin: layout.$normal-gap 0 layout.$normal-gap layout.$large-gap;
|
margin: layout.$normal-gap 0 layout.$normal-gap layout.$large-gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
em {
|
em {
|
||||||
background-color: colors.$teal-300;
|
background-color: colors.$teal-300;
|
||||||
padding: 0 layout.$small-gap 0 layout.$small-gap;
|
padding: 0 layout.$small-gap 0 layout.$small-gap;
|
||||||
}
|
}
|
||||||
|
|
||||||
:any-link,
|
:any-link,
|
||||||
a[href] {
|
a[href] {
|
||||||
color: colors.$main-text;
|
color: colors.$main-text;
|
||||||
transition: color motion.$subtle;
|
transition: color motion.$subtle;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: colors.$blue-800;
|
color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
@extend %narrow-content-gutter;
|
@extend %narrow-content-gutter;
|
||||||
$border: 0.5em solid colors.$teal-300;
|
$border: 0.5em solid colors.$teal-300;
|
||||||
border-top: $border;
|
border-top: $border;
|
||||||
border-bottom: $border;
|
border-bottom: $border;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta-link {
|
.cta-link {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0 layout.$normal-gap;
|
padding: 0 layout.$normal-gap;
|
||||||
max-width: layout.$narrow-content-width;
|
max-width: layout.$narrow-content-width;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
line-height: 3rem;
|
line-height: 3rem;
|
||||||
border: 1px solid colors.$main-text;
|
border: 1px solid colors.$main-text;
|
||||||
transition: font motion.$subtle, border-color motion.$subtle, color motion.$subtle;
|
transition: font motion.$subtle, border-color motion.$subtle,
|
||||||
|
color motion.$subtle;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: colors.$blue-800;
|
border-color: colors.$blue-800;
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
font-size: 110%;
|
font-size: 110%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.link-grid {
|
ul.link-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 1fr;
|
grid-template-columns: 1fr;
|
||||||
gap: layout.$larger-gap layout.$normal-gap;
|
gap: layout.$larger-gap layout.$normal-gap;
|
||||||
justify-items: center;
|
justify-items: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
@media screen and (min-width: layout.$breakpoint) {
|
@media screen and (min-width: layout.$breakpoint) {
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
}
|
}
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
> a {
|
> a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: layout.$normal-gap;
|
padding: layout.$normal-gap;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: colors.$gray-600;
|
color: colors.$gray-600;
|
||||||
transition: color motion.$subtle, box-shadow motion.$subtle;
|
transition: color motion.$subtle, box-shadow motion.$subtle;
|
||||||
|
|
||||||
> img {
|
> img {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto layout.$small-gap auto;
|
margin: 0 auto layout.$small-gap auto;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 6rem;
|
max-height: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@include colors.card-shadow;
|
@include colors.card-shadow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,35 +3,35 @@
|
||||||
@use '../lib/typography';
|
@use '../lib/typography';
|
||||||
|
|
||||||
.page-section {
|
.page-section {
|
||||||
padding: layout.$large-gap;
|
padding: layout.$large-gap;
|
||||||
|
|
||||||
&.inverse {
|
&.inverse {
|
||||||
color: colors.$inverse-text;
|
color: colors.$inverse-text;
|
||||||
background-color: colors.$blue-800;
|
background-color: colors.$blue-800;
|
||||||
|
|
||||||
h2:after {
|
h2:after {
|
||||||
background-color: colors.$gray-50;
|
background-color: colors.$gray-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
:any-link,
|
:any-link,
|
||||||
a[href] {
|
a[href] {
|
||||||
color: colors.$gray-300;
|
color: colors.$gray-300;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: colors.$yellow-500;
|
color: colors.$yellow-500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.cta-link {
|
.cta-link {
|
||||||
border-color: colors.$gray-300;
|
border-color: colors.$gray-300;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: colors.$yellow-500;
|
border-color: colors.$yellow-500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.footer {
|
&.footer {
|
||||||
background-color: colors.$teal-500;
|
background-color: colors.$teal-500;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,130 +3,130 @@
|
||||||
@use '../lib/typography';
|
@use '../lib/typography';
|
||||||
|
|
||||||
@mixin header-item {
|
@mixin header-item {
|
||||||
padding: 0 layout.$large-gap;
|
padding: 0 layout.$large-gap;
|
||||||
line-height: 4rem;
|
line-height: 4rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The site logo text. More specific styles for this element are also present
|
// The site logo text. More specific styles for this element are also present
|
||||||
// underneath .site-header.
|
// underneath .site-header.
|
||||||
.site-logo {
|
.site-logo {
|
||||||
margin: 0 layout.$large-gap;
|
margin: 0 layout.$large-gap;
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The navigation is present twice on the site: once in the header and once in
|
// The navigation is present twice on the site: once in the header and once in
|
||||||
// the footer. The former also has some specific styles (see .site-header
|
// the footer. The former also has some specific styles (see .site-header
|
||||||
// below).
|
// below).
|
||||||
.site-navigation {
|
.site-navigation {
|
||||||
&.horizontal {
|
&.horizontal {
|
||||||
> ul {
|
> ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
> li {
|
> li {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@include header-item;
|
@include header-item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> ul {
|
> ul {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
display: block;
|
display: block;
|
||||||
padding: layout.$small-gap;
|
padding: layout.$small-gap;
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-mobile-navigation {
|
.site-mobile-navigation {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
> summary {
|
> summary {
|
||||||
display: block;
|
display: block;
|
||||||
@include header-item;
|
@include header-item;
|
||||||
}
|
}
|
||||||
|
|
||||||
&[open] {
|
&[open] {
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
|
|
||||||
> summary {
|
> summary {
|
||||||
// The positioning requires that the header component has relative
|
// The positioning requires that the header component has relative
|
||||||
// positioning.
|
// positioning.
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
color: colors.$blue-800;
|
color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is the next site navigation block (the one that's visible on desktop),
|
// This is the next site navigation block (the one that's visible on desktop),
|
||||||
// while...
|
// while...
|
||||||
+ .site-navigation {
|
+ .site-navigation {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ... this here is the one inside the mobile-only <details> block.
|
// ... this here is the one inside the mobile-only <details> block.
|
||||||
> .site-navigation {
|
> .site-navigation {
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: calc(100% - #{2 * layout.$normal-gap});
|
width: calc(100% - #{2 * layout.$normal-gap});
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: layout.$breakpoint) {
|
@media screen and (min-width: layout.$breakpoint) {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
+ .site-navigation {
|
+ .site-navigation {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-header {
|
.site-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
// This container needs to wrap because when the navigation is open on small
|
// This container needs to wrap because when the navigation is open on small
|
||||||
// screens, we want it to overflow into its own line.
|
// screens, we want it to overflow into its own line.
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
// Relative positioning is required here so that we can fake the menu button's
|
// Relative positioning is required here so that we can fake the menu button's
|
||||||
// location on mobile.
|
// location on mobile.
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
background-color: colors.$main-background;
|
background-color: colors.$main-background;
|
||||||
@include colors.block-shadow;
|
@include colors.block-shadow;
|
||||||
|
|
||||||
> .site-logo {
|
> .site-logo {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
font-size: typography.$subheading-size;
|
font-size: typography.$subheading-size;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@include header-item;
|
@include header-item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.site-footer {
|
.site-footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: layout.$normal-gap;
|
gap: layout.$normal-gap;
|
||||||
|
|
||||||
.site-navigation a {
|
.site-navigation a {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,48 +21,48 @@
|
||||||
// tabs is targeted by the URL's hash, it is shown instead and the default tab
|
// tabs is targeted by the URL's hash, it is shown instead and the default tab
|
||||||
// is hidden.
|
// is hidden.
|
||||||
.tabs-widget {
|
.tabs-widget {
|
||||||
@extend %content;
|
@extend %content;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin-top: #{-1 * layout.$large-gap};
|
margin-top: #{-1 * layout.$large-gap};
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 0 layout.$normal-gap;
|
margin: 0 layout.$normal-gap;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .tab {
|
> .tab {
|
||||||
flex: 100% 1;
|
flex: 100% 1;
|
||||||
order: 9999;
|
order: 9999;
|
||||||
display: none;
|
display: none;
|
||||||
margin: layout.$large-gap 0;
|
margin: layout.$large-gap 0;
|
||||||
padding: layout.$large-gap;
|
padding: layout.$large-gap;
|
||||||
background: colors.$gray-50;
|
background: colors.$gray-50;
|
||||||
@include colors.card-shadow;
|
@include colors.card-shadow;
|
||||||
|
|
||||||
&:last-of-type,
|
&:last-of-type,
|
||||||
&:target {
|
&:target {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
+ a {
|
+ a {
|
||||||
font-weight: typography.$emphasized-weight;
|
font-weight: typography.$emphasized-weight;
|
||||||
color: colors.$blue-800;
|
color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:target {
|
&:target {
|
||||||
~ .tab {
|
~ .tab {
|
||||||
display: none;
|
display: none;
|
||||||
|
|
||||||
+ a {
|
+ a {
|
||||||
font-weight: inherit;
|
font-weight: inherit;
|
||||||
color: inherit;
|
color: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,107 +4,108 @@
|
||||||
@use '../lib/motion';
|
@use '../lib/motion';
|
||||||
|
|
||||||
.timeline {
|
.timeline {
|
||||||
$stampSize: 4rem;
|
$stampSize: 4rem;
|
||||||
$lineWeight: 0.2rem;
|
$lineWeight: 0.2rem;
|
||||||
$itemSpacing: layout.$normal-gap;
|
$itemSpacing: layout.$normal-gap;
|
||||||
|
|
||||||
@extend %content-gutter;
|
@extend %content-gutter;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
@media screen and (min-width: layout.$breakpoint) {
|
@media screen and (min-width: layout.$breakpoint) {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
position: relative;
|
position: relative;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
margin-left: layout.$normal-gap;
|
margin-left: layout.$normal-gap;
|
||||||
margin-bottom: $itemSpacing;
|
margin-bottom: $itemSpacing;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
right: calc(100% + #{layout.$normal-gap + math.div($stampSize, 2)});
|
right: calc(100% + #{layout.$normal-gap + math.div($stampSize, 2)});
|
||||||
bottom: #{-1 * $itemSpacing};
|
bottom: #{-1 * $itemSpacing};
|
||||||
width: $lineWeight;
|
width: $lineWeight;
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
transform: translateX(50%);
|
transform: translateX(50%);
|
||||||
transition: background-color motion.$subtle;
|
transition: background-color motion.$subtle;
|
||||||
}
|
}
|
||||||
|
|
||||||
> h3:first-child {
|
> h3:first-child {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
margin-left: layout.$large-gap;
|
margin-left: layout.$large-gap;
|
||||||
line-height: $stampSize;
|
line-height: $stampSize;
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: calc(100% + #{layout.$small-gap});
|
right: calc(100% + #{layout.$small-gap});
|
||||||
top: 50%;
|
top: 50%;
|
||||||
width: 4rem;
|
width: 4rem;
|
||||||
height: $lineWeight;
|
height: $lineWeight;
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
transition: background-color motion.$subtle;
|
transition: background-color motion.$subtle;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .stamp {
|
> .stamp {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: $stampSize;
|
width: $stampSize;
|
||||||
height: $stampSize;
|
height: $stampSize;
|
||||||
z-index: 10; // To lift it above the line.
|
z-index: 10; // To lift it above the line.
|
||||||
border: $lineWeight solid colors.$gray-300;
|
border: $lineWeight solid colors.$gray-300;
|
||||||
border-radius: 100%;
|
border-radius: 100%;
|
||||||
line-height: #{$stampSize - 2 * $lineWeight};
|
line-height: #{$stampSize - 2 * $lineWeight};
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background-color: colors.$gray-50;
|
background-color: colors.$gray-50;
|
||||||
transition: border-color motion.$subtle, background-color motion.$subtle, color motion.$subtle;
|
transition: border-color motion.$subtle, background-color motion.$subtle,
|
||||||
|
color motion.$subtle;
|
||||||
|
|
||||||
&.small {
|
&.small {
|
||||||
background-color: colors.$gray-300;
|
background-color: colors.$gray-300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
> p {
|
> p {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
> .stamp {
|
> .stamp {
|
||||||
border-color: colors.$blue-800;
|
border-color: colors.$blue-800;
|
||||||
background-color: colors.$blue-800;
|
background-color: colors.$blue-800;
|
||||||
color: colors.$inverse-text;
|
color: colors.$inverse-text;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
&::before,
|
&::before,
|
||||||
> h3:first-child::after {
|
> h3:first-child::after {
|
||||||
background-color: colors.$blue-800;
|
background-color: colors.$blue-800;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
|
|
||||||
> .content {
|
> .content {
|
||||||
padding-bottom: layout.$normal-gap;
|
padding-bottom: layout.$normal-gap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ .timeline {
|
+ .timeline {
|
||||||
margin-top: #{-1 * layout.$normal-gap};
|
margin-top: #{-1 * layout.$normal-gap};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,115 +10,164 @@
|
||||||
@use 'lib/motion';
|
@use 'lib/motion';
|
||||||
|
|
||||||
.finish-hero {
|
.finish-hero {
|
||||||
@keyframes finish-hero {
|
@keyframes finish-hero {
|
||||||
0% { stroke-width: 3px; }
|
0% {
|
||||||
10% { stroke-width: 3px; }
|
stroke-width: 3px;
|
||||||
20% { stroke-width: 5px; }
|
}
|
||||||
60% { stroke-width: 5px; }
|
10% {
|
||||||
100% { stroke-width: 3px; }
|
stroke-width: 3px;
|
||||||
}
|
}
|
||||||
|
20% {
|
||||||
|
stroke-width: 5px;
|
||||||
|
}
|
||||||
|
60% {
|
||||||
|
stroke-width: 5px;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stroke-width: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
display: block;
|
display: block;
|
||||||
height: 15vmin;
|
height: 15vmin;
|
||||||
margin: layout.$huge-gap auto;
|
margin: layout.$huge-gap auto;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
stroke-linecap: round;
|
stroke-linecap: round;
|
||||||
stroke-miterlimit: 10;
|
stroke-miterlimit: 10;
|
||||||
animation: motion.$prominent 0s 1 normal both running finish-hero;
|
animation: motion.$prominent 0s 1 normal both running finish-hero;
|
||||||
|
|
||||||
> .stroke-gradient {
|
> .stroke-gradient {
|
||||||
$idle-color: colors.$gray-900;
|
$idle-color: colors.$gray-900;
|
||||||
$colors: [
|
$colors: [ $idle-color $idle-color $idle-color colors.$blue-500
|
||||||
$idle-color
|
colors.$teal-500 colors.$yellow-500 colors.$teal-500 colors.$gray-300
|
||||||
$idle-color
|
colors.$yellow-500 colors.$blue-500 colors.$gray-300 $idle-color
|
||||||
$idle-color
|
$idle-color $idle-color ];
|
||||||
colors.$blue-500
|
|
||||||
colors.$teal-500
|
|
||||||
colors.$yellow-500
|
|
||||||
colors.$teal-500
|
|
||||||
colors.$gray-300
|
|
||||||
colors.$yellow-500
|
|
||||||
colors.$blue-500
|
|
||||||
colors.$gray-300
|
|
||||||
$idle-color
|
|
||||||
$idle-color
|
|
||||||
$idle-color
|
|
||||||
];
|
|
||||||
|
|
||||||
@for $i from 1 through 4 {
|
@for $i from 1 through 4 {
|
||||||
> stop:nth-of-type(#{$i}) {
|
> stop:nth-of-type(#{$i}) {
|
||||||
@keyframes finish-stroke-gradient-#{$i} {
|
@keyframes finish-stroke-gradient-#{$i} {
|
||||||
0% { stop-color: $idle-color; }
|
0% {
|
||||||
15% { stop-color: $idle-color; }
|
stop-color: $idle-color;
|
||||||
// This is some which magic that chooses the correct colors for each
|
}
|
||||||
// stop - don't change it unless you know what you are doing! In
|
15% {
|
||||||
// general, the output will look something like this:
|
stop-color: $idle-color;
|
||||||
// <animation stop>: <color stop 1> <color stop 2> ...
|
}
|
||||||
// 20%: 4 3 2 1
|
// This is some which magic that chooses the correct colors for each
|
||||||
// 25%: 5 4 3 2
|
// stop - don't change it unless you know what you are doing! In
|
||||||
// 35%: 6 5 4 3
|
// general, the output will look something like this:
|
||||||
// ...
|
// <animation stop>: <color stop 1> <color stop 2> ...
|
||||||
// In order to achieve the 'moving' effect, we make sure that the
|
// 20%: 4 3 2 1
|
||||||
// first and last three colors match the ones we are given at 15% and
|
// 25%: 5 4 3 2
|
||||||
// 70% (before and after the core animation).
|
// 35%: 6 5 4 3
|
||||||
@for $j from 1 to list.length($colors) - 3 {
|
// ...
|
||||||
#{15% + $j * 5%} {
|
// In order to achieve the 'moving' effect, we make sure that the
|
||||||
stop-color: list.nth($colors, 4 + $j - $i);
|
// first and last three colors match the ones we are given at 15% and
|
||||||
}
|
// 70% (before and after the core animation).
|
||||||
}
|
@for $j from 1 to list.length($colors) - 3 {
|
||||||
70% { stop-color: $idle-color; }
|
#{15% + $j * 5%} {
|
||||||
100% { stop-color: $idle-color; }
|
stop-color: list.nth($colors, 4 + $j - $i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
stop-color: $idle-color;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
stop-color: $idle-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
animation:
|
animation: motion.$prominent
|
||||||
motion.$prominent 0s 1 normal both running finish-stroke-gradient-#{$i};
|
0s
|
||||||
}
|
1
|
||||||
}
|
normal
|
||||||
}
|
both
|
||||||
|
running
|
||||||
|
finish-stroke-gradient-#{$i};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
> .cable {
|
> .cable {
|
||||||
@keyframes finish-hero-cable {
|
@keyframes finish-hero-cable {
|
||||||
0% { transform: translateX(0.5rem); }
|
0% {
|
||||||
20% { transform: translateX(0.5rem); }
|
transform: translateX(0.5rem);
|
||||||
70% { transform: translateX(0.5rem); }
|
}
|
||||||
100% { transform: none; }
|
20% {
|
||||||
}
|
transform: translateX(0.5rem);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: translateX(0.5rem);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
animation: motion.$prominent 0s 1 normal both running finish-hero-cable;
|
animation: motion.$prominent 0s 1 normal both running finish-hero-cable;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .plug {
|
> .plug {
|
||||||
@keyframes finish-hero-plug {
|
@keyframes finish-hero-plug {
|
||||||
0% { transform: translateX(-0.5rem); }
|
0% {
|
||||||
20% { transform: translateX(-0.5rem); }
|
transform: translateX(-0.5rem);
|
||||||
70% { transform: translateX(-0.5rem); }
|
}
|
||||||
100% { transform: none; }
|
20% {
|
||||||
}
|
transform: translateX(-0.5rem);
|
||||||
@keyframes finish-hero-plug-transition {
|
}
|
||||||
0% { fill: colors.$gray-900; }
|
70% {
|
||||||
100% { fill: colors.$gray-600; }
|
transform: translateX(-0.5rem);
|
||||||
}
|
}
|
||||||
@keyframes finish-hero-plug-idle {
|
100% {
|
||||||
0% { fill: colors.$gray-600; }
|
transform: none;
|
||||||
25% { fill: colors.$teal-600; }
|
}
|
||||||
50% { fill: colors.$yellow-600; }
|
}
|
||||||
75% { fill: colors.$blue-800; }
|
@keyframes finish-hero-plug-transition {
|
||||||
100% { fill: colors.$gray-600; }
|
0% {
|
||||||
}
|
fill: colors.$gray-900;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
fill: colors.$gray-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes finish-hero-plug-idle {
|
||||||
|
0% {
|
||||||
|
fill: colors.$gray-600;
|
||||||
|
}
|
||||||
|
25% {
|
||||||
|
fill: colors.$teal-600;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
fill: colors.$yellow-600;
|
||||||
|
}
|
||||||
|
75% {
|
||||||
|
fill: colors.$blue-800;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
fill: colors.$gray-600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
animation: motion.$prominent 0s 1 normal both running finish-hero-plug,
|
animation: motion.$prominent 0s 1 normal both running finish-hero-plug,
|
||||||
motion.$gentle 0.7s 1 normal forwards running finish-hero-plug-transition,
|
motion.$gentle 0.7s 1 normal forwards running finish-hero-plug-transition,
|
||||||
motion.$background 1s infinite normal none running finish-hero-plug-idle;
|
motion.$background 1s infinite normal none running finish-hero-plug-idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .contacts {
|
> .contacts {
|
||||||
@keyframes finish-hero-contacts {
|
@keyframes finish-hero-contacts {
|
||||||
0% { transform: translateX(0rem); }
|
0% {
|
||||||
20% { transform: translateX(-0.7rem); }
|
transform: translateX(0rem);
|
||||||
70% { transform: translateX(-0.7rem); }
|
}
|
||||||
100% { transform: none; }
|
20% {
|
||||||
}
|
transform: translateX(-0.7rem);
|
||||||
|
}
|
||||||
|
70% {
|
||||||
|
transform: translateX(-0.7rem);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
animation: motion.$prominent 0s 1 normal both running finish-hero-contacts;
|
animation: motion.$prominent 0s 1 normal both running finish-hero-contacts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@ $main-background: $gray-50;
|
||||||
$inverse-text: $gray-50;
|
$inverse-text: $gray-50;
|
||||||
|
|
||||||
@mixin block-shadow {
|
@mixin block-shadow {
|
||||||
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
|
||||||
}
|
}
|
||||||
|
|
||||||
@mixin card-shadow($base-color: $gray-900) {
|
@mixin card-shadow($base-color: $gray-900) {
|
||||||
box-shadow: 0.1rem 0.4rem 0.4rem #{transparentize($base-color, 0.9)},
|
box-shadow: 0.1rem 0.4rem 0.4rem #{transparentize($base-color, 0.9)},
|
||||||
0.25rem 1rem 1rem #{transparentize($base-color, 0.9)};
|
0.25rem 1rem 1rem #{transparentize($base-color, 0.9)};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,39 +11,39 @@ $content-width: 60rem;
|
||||||
$wide-content-width: 80rem;
|
$wide-content-width: 80rem;
|
||||||
|
|
||||||
%narrow-content {
|
%narrow-content {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
max-width: $narrow-content-width;
|
max-width: $narrow-content-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
%narrow-content-gutter {
|
%narrow-content-gutter {
|
||||||
margin: $normal-gap auto;
|
margin: $normal-gap auto;
|
||||||
max-width: $narrow-content-width;
|
max-width: $narrow-content-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
%content {
|
%content {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
max-width: $content-width;
|
max-width: $content-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
%content-gutter {
|
%content-gutter {
|
||||||
margin: $normal-gap $normal-gap;
|
margin: $normal-gap $normal-gap;
|
||||||
|
|
||||||
@media screen and (min-width: $breakpoint) {
|
@media screen and (min-width: $breakpoint) {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
max-width: $content-width;
|
max-width: $content-width;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
%wide-content {
|
%wide-content {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
margin-right: auto;
|
margin-right: auto;
|
||||||
max-width: $wide-content-width;
|
max-width: $wide-content-width;
|
||||||
}
|
}
|
||||||
|
|
||||||
%wide-content-gutter {
|
%wide-content-gutter {
|
||||||
margin: $normal-gap auto;
|
margin: $normal-gap auto;
|
||||||
max-width: $wide-content-width;
|
max-width: $wide-content-width;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
$subtle: 0.1s cubic-bezier(0.56, 0.03, 0.35, 0.9);
|
$subtle: 0.1s cubic-bezier(0.56, 0.03, 0.35, 0.9);
|
||||||
$gentle: 0.2s cubic-bezier(1, 0.11, 0.41, 0.69);
|
$gentle: 0.2s cubic-bezier(1, 0.11, 0.41, 0.69);
|
||||||
$prominent: 0.7s cubic-bezier(.45,.16,.38,.7);
|
$prominent: 0.7s cubic-bezier(0.45, 0.16, 0.38, 0.7);
|
||||||
$background: 8s cubic-bezier(.45,.16,.38,.7);
|
$background: 8s cubic-bezier(0.45, 0.16, 0.38, 0.7);
|
||||||
|
|
|
||||||
|
|
@ -11,45 +11,45 @@ $base-line-height: 1.5;
|
||||||
$heading-line-height: 1.3;
|
$heading-line-height: 1.3;
|
||||||
|
|
||||||
$comfortaa-weights: (
|
$comfortaa-weights: (
|
||||||
'Light': 300,
|
'Light': 300,
|
||||||
'Regular': 400,
|
'Regular': 400,
|
||||||
'Medium': 500,
|
'Medium': 500,
|
||||||
'Semi-bold': 600,
|
'Semi-bold': 600,
|
||||||
'Bold': 700,
|
'Bold': 700,
|
||||||
);
|
);
|
||||||
|
|
||||||
@mixin root-config {
|
@mixin root-config {
|
||||||
@each $name, $weight in $comfortaa-weights {
|
@each $name, $weight in $comfortaa-weights {
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Comfortaa';
|
font-family: 'Comfortaa';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: $weight;
|
font-weight: $weight;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url('/assets/fonts/Comfortaa-#{$name}.ttf') format('truetype');
|
src: url('/assets/fonts/Comfortaa-#{$name}.ttf') format('truetype');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'Comfortaa Variable';
|
font-family: 'Comfortaa Variable';
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-display: swap;
|
font-display: swap;
|
||||||
src: url('/assets/fonts/Comfortaa-VariableFont_wght.ttf') format('truetype');
|
src: url('/assets/fonts/Comfortaa-VariableFont_wght.ttf') format('truetype');
|
||||||
}
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
$fallback-fonts: Roboto, Arial, sans-serif;
|
$fallback-fonts: Roboto, Arial, sans-serif;
|
||||||
|
|
||||||
font-size: 125%; // Scale from 16px to 20px
|
font-size: 125%; // Scale from 16px to 20px
|
||||||
font-family: Comfortaa, $fallback-fonts;
|
font-family: Comfortaa, $fallback-fonts;
|
||||||
font-weight: $normal-weight;
|
font-weight: $normal-weight;
|
||||||
|
|
||||||
@supports (font-variation-settings: normal) {
|
@supports (font-variation-settings: normal) {
|
||||||
font-family: 'Comfortaa Variable', $fallback-fonts;
|
font-family: 'Comfortaa Variable', $fallback-fonts;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-size: $base-size;
|
font-size: $base-size;
|
||||||
line-height: $base-line-height;
|
line-height: $base-line-height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue