refactor: convert files from spaces to tabs

This commit is contained in:
Stefan Imhoff
2022-08-24 10:15:43 +02:00
parent 1685aa561f
commit d555778570
69 changed files with 39605 additions and 39600 deletions

View File

@@ -7,89 +7,89 @@ const filters = require('./src/utils/filters.js');
const shortcodes = require('./src/utils/shortcodes.js'); const shortcodes = require('./src/utils/shortcodes.js');
module.exports = function (config) { module.exports = function (config) {
// Plugins // Plugins
config.addPlugin(pluginRssFeed); config.addPlugin(pluginRssFeed);
if (process.env.ELEVENTY_ENV == 'production') { if (process.env.ELEVENTY_ENV == 'production') {
config.addPlugin(pluginLazyImages); config.addPlugin(pluginLazyImages);
} }
// Markdown It // Markdown It
let markdownIt = require('markdown-it'); let markdownIt = require('markdown-it');
let markdownItFootnotes = require('markdown-it-footnote'); let markdownItFootnotes = require('markdown-it-footnote');
let markdownItSub = require('markdown-it-sub'); let markdownItSub = require('markdown-it-sub');
let markdownItSup = require('markdown-it-sup'); let markdownItSup = require('markdown-it-sup');
let markdownItExternalAnchor = require('markdown-it-external-anchor'); let markdownItExternalAnchor = require('markdown-it-external-anchor');
let options = { let options = {
html: true, html: true,
}; };
let markdownLib = markdownIt(options) let markdownLib = markdownIt(options)
.use(markdownItFootnotes) .use(markdownItFootnotes)
.use(markdownItExternalAnchor, { .use(markdownItExternalAnchor, {
domain: 'hamburg.stefanimhoff.de', domain: 'hamburg.stefanimhoff.de',
class: 'external', class: 'external',
}) })
.use(markdownItSub) .use(markdownItSub)
.use(markdownItSup); .use(markdownItSup);
config.setLibrary('md', markdownLib); config.setLibrary('md', markdownLib);
// Compress and combine JS files // Compress and combine JS files
config.addFilter('jsmin', require('./src/utils/minify-js.js')); config.addFilter('jsmin', require('./src/utils/minify-js.js'));
// Minify the HTML in production // Minify the HTML in production
if (process.env.ELEVENTY_ENV == 'production') { if (process.env.ELEVENTY_ENV == 'production') {
config.addTransform('htmlmin', require('./src/utils/minify-html.js')); config.addTransform('htmlmin', require('./src/utils/minify-html.js'));
} }
// Shortcodes // Shortcodes
config.addShortcode('email', shortcodes.email); config.addShortcode('email', shortcodes.email);
config.addShortcode('map', shortcodes.map); config.addShortcode('map', shortcodes.map);
config.addShortcode('youtube', shortcodes.youtube); config.addShortcode('youtube', shortcodes.youtube);
// Filters // Filters
Object.keys(filters).forEach((filterName) => { Object.keys(filters).forEach((filterName) => {
config.addFilter(filterName, filters[filterName]); config.addFilter(filterName, filters[filterName]);
}); });
config.addFilter('nbsp', filterNbsp(2, 15)); config.addFilter('nbsp', filterNbsp(2, 15));
// Watch for changes and reload // Watch for changes and reload
config.addWatchTarget('src/assets'); config.addWatchTarget('src/assets');
// Copy static files to dist // Copy static files to dist
config.addPassthroughCopy({ config.addPassthroughCopy({
'src/static/**/*.{xml,html,ico}': '.', 'src/static/**/*.{xml,html,ico}': '.',
}); });
config.addPassthroughCopy({ config.addPassthroughCopy({
'src/static/.well-known/*': '.well-known', 'src/static/.well-known/*': '.well-known',
}); });
config.addPassthroughCopy({ config.addPassthroughCopy({
'src/downloads': 'downloads', 'src/downloads': 'downloads',
}); });
config.addPassthroughCopy({ config.addPassthroughCopy({
'src/assets/fonts': 'assets/fonts', 'src/assets/fonts': 'assets/fonts',
}); });
config.addPassthroughCopy({ config.addPassthroughCopy({
'src/assets/images': 'assets/images', 'src/assets/images': 'assets/images',
}); });
// Deep-Merge // Deep-Merge
config.setDataDeepMerge(true); config.setDataDeepMerge(true);
// Set input and output folders // Set input and output folders
return { return {
dir: { dir: {
input: 'src', input: 'src',
data: 'data', data: 'data',
includes: 'includes', includes: 'includes',
layouts: 'layouts', layouts: 'layouts',
output: 'dist', output: 'dist',
}, },
templateFormats: ['njk', 'md', '11ty.js'], templateFormats: ['njk', 'md', '11ty.js'],
htmlTemplateEngine: 'njk', htmlTemplateEngine: 'njk',
dataTemplateEngine: 'njk', dataTemplateEngine: 'njk',
markdownTemplateEngine: 'njk', markdownTemplateEngine: 'njk',
passthroughFileCopy: true, passthroughFileCopy: true,
}; };
}; };

View File

@@ -1,15 +1,15 @@
{ {
"env": { "env": {
"es6": true, "es6": true,
"node": true, "node": true,
"browser": true "browser": true
}, },
"extends": ["eslint:recommended", "plugin:prettier/recommended"], "extends": ["eslint:recommended", "plugin:prettier/recommended"],
"plugins": ["prettier"], "plugins": ["prettier"],
"parserOptions": { "parserOptions": {
"sourceType": "module" "sourceType": "module"
}, },
"rules": { "rules": {
"prettier/prettier": "error" "prettier/prettier": "error"
} }
} }

View File

@@ -1,35 +1,35 @@
{ {
"plugins": [ "plugins": [
"stylelint-order", "stylelint-order",
"stylelint-config-rational-order/plugin", "stylelint-config-rational-order/plugin",
"stylelint-a11y", "stylelint-a11y",
"stylelint-high-performance-animation", "stylelint-high-performance-animation",
"stylelint-prettier" "stylelint-prettier"
], ],
"extends": [ "extends": [
"stylelint-config-recommended", "stylelint-config-recommended",
"stylelint-a11y/recommended", "stylelint-a11y/recommended",
"stylelint-prettier/recommended" "stylelint-prettier/recommended"
], ],
"syntax": "scss", "syntax": "scss",
"rules": { "rules": {
"property-no-unknown": [ "property-no-unknown": [
true, true,
{ {
"ignoreProperties": ["suffix", "symbols", "system"] "ignoreProperties": ["suffix", "symbols", "system"]
} }
], ],
"no-descending-specificity": null, "no-descending-specificity": null,
"order/order": ["custom-properties", "declarations"], "order/order": ["custom-properties", "declarations"],
"order/properties-alphabetical-order": true, "order/properties-alphabetical-order": true,
"plugin/no-low-performance-animation-properties": true, "plugin/no-low-performance-animation-properties": true,
"at-rule-no-unknown": [ "at-rule-no-unknown": [
true, true,
{ {
"ignoreAtRules": ["define-placeholder", "extend"] "ignoreAtRules": ["define-placeholder", "extend"]
} }
], ],
"string-quotes": "single", "string-quotes": "single",
"prettier/prettier": true "prettier/prettier": true
} }
} }

View File

@@ -1,3 +1,3 @@
{ {
"presets": ["@babel/preset-env"] "presets": ["@babel/preset-env"]
} }

View File

@@ -16,94 +16,91 @@ const svgSprite = require('gulp-svg-sprite');
* Package JavaScript with Babel and Browserify * Package JavaScript with Babel and Browserify
*/ */
task('js', () => { task('js', () => {
return browserify(['./src/assets/scripts/main.js'], { return browserify(['./src/assets/scripts/main.js'], {
debug: true, debug: true,
}) })
.transform(babel) .transform(babel)
.bundle() .bundle()
.on('error', function (err) { .on('error', function (err) {
console.error(err); console.error(err);
this.emit('end'); this.emit('end');
}) })
.pipe(source('main.js')) .pipe(source('main.js'))
.pipe(buffer()) .pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true })) .pipe(sourcemaps.init({ loadMaps: true }))
.pipe(sourcemaps.write('.')) .pipe(sourcemaps.write('.'))
.pipe(dest('./dist/assets/scripts')); .pipe(dest('./dist/assets/scripts'));
}); });
/** /**
* Create CSS and Sourcemaps with PostCSS * Create CSS and Sourcemaps with PostCSS
*/ */
task('css', function () { task('css', function () {
return src([ return src(['./src/assets/styles/*.css', './src/assets/styles/critical/*.css'])
'./src/assets/styles/*.css', .pipe(plumber())
'./src/assets/styles/critical/*.css', .pipe(sourcemaps.init())
]) .pipe(postcss())
.pipe(plumber()) .pipe(sourcemaps.write('.'))
.pipe(sourcemaps.init()) .pipe(dest('./dist/assets/styles'));
.pipe(postcss())
.pipe(sourcemaps.write('.'))
.pipe(dest('./dist/assets/styles'));
}); });
/** /**
* Create CSS with PostCSS for production * Create CSS with PostCSS for production
*/ */
task('css:production', function () { task('css:production', function () {
return src(['./src/assets/styles/*.css']) return src(['./src/assets/styles/*.css'])
.pipe(plumber()) .pipe(plumber())
.pipe(postcss()) .pipe(postcss())
.pipe(dest('./dist/assets/styles')); .pipe(dest('./dist/assets/styles'));
}); });
/** /**
* Copy critical CSS files to project folder * Copy critical CSS files to project folder
*/ */
task('css:critical', function () { task('css:critical', function () {
return src(['./src/assets/styles/critical/*.css']) return src(['./src/assets/styles/critical/*.css'])
.pipe(plumber()) .pipe(plumber())
.pipe(postcss()) .pipe(postcss())
.pipe(dest('./src/includes/critical')); .pipe(dest('./src/includes/critical'));
}); });
/** /**
* Create SVG sprite map from SVG files * Create SVG sprite map from SVG files
*/ */
task('svg', () => { task('svg', () => {
return src('./src/icons/*.svg') return src('./src/icons/*.svg')
.pipe(plumber()) .pipe(plumber())
.pipe( .pipe(
svgSprite({ svgSprite({
mode: { mode: {
symbol: { symbol: {
dest: '.', dest: '.',
sprite: 'icons.svg', sprite: 'icons.svg',
}, },
svg: { svg: {
xmlDeclaration: false, xmlDeclaration: false,
doctypeDeclaration: false, doctypeDeclaration: false,
}, },
}, },
}) })
) )
.pipe(dest('src/includes')); .pipe(dest('src/includes'));
}); });
/** /**
* Optimize and minimize images * Optimize and minimize images
*/ */
task('optimize:images', () => { task('optimize:images', () => {
return src('src/assets/images/**/*.{jpg,jpeg,png,gif,svg}') return src('src/assets/images/**/*.{jpg,jpeg,png,gif,svg}')
.pipe( .pipe(
imagemin({ imagemin({
optimizationLevel: 3, optimizationLevel: 3,
progressive: true, progressive: true,
interlaced: true, interlaced: true,
}) })
) )
.pipe(dest('src/assets/images/')) .pipe(dest('src/assets/images/'))
.pipe(size()); .pipe(size());
}); });
/** /**
@@ -115,8 +112,8 @@ task('build', parallel('js', 'css:production', 'css:critical'));
* Watch for changes in files * Watch for changes in files
*/ */
task('watch', () => { task('watch', () => {
watch('./src/assets/scripts/**/*.js', series('js')); watch('./src/assets/scripts/**/*.js', series('js'));
watch('./src/assets/styles/**/*.css', series('css')); watch('./src/assets/styles/**/*.css', series('css'));
}); });
/** /**

76376
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,91 +1,91 @@
{ {
"name": "website-11ty-hamburg.stefanimhoff.de", "name": "website-11ty-hamburg.stefanimhoff.de",
"version": "1.0.0", "version": "1.0.0",
"description": "Source code of my travel blog", "description": "Source code of my travel blog",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"build": "ELEVENTY_ENV=production npm-run-all build:assets build:html build:sw", "build": "ELEVENTY_ENV=production npm-run-all build:assets build:html build:sw",
"build:assets": "gulp build", "build:assets": "gulp build",
"build:html": "eleventy", "build:html": "eleventy",
"build:sw": "workbox generateSW workbox.config.js", "build:sw": "workbox generateSW workbox.config.js",
"clean": "npx del dist", "clean": "npx del dist",
"debug": "DEBUG=* npx eleventy", "debug": "DEBUG=* npx eleventy",
"deploy": "netlify deploy --prod", "deploy": "netlify deploy --prod",
"deploy:preview": "netlify deploy", "deploy:preview": "netlify deploy",
"dev": "ELEVENTY_ENV=development npm run watch", "dev": "ELEVENTY_ENV=development npm run watch",
"plop": "plop", "plop": "plop",
"prebuild": "npm run clean", "prebuild": "npm run clean",
"prestart": "npm run clean", "prestart": "npm run clean",
"publish": "npm-run-all build deploy", "publish": "npm-run-all build deploy",
"start": "netlify dev", "start": "netlify dev",
"svg": "gulp svg", "svg": "gulp svg",
"watch": "npm-run-all --parallel watch:*", "watch": "npm-run-all --parallel watch:*",
"watch:assets": "gulp", "watch:assets": "gulp",
"watch:html": "eleventy --serve" "watch:html": "eleventy --serve"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/kogakure/website-11ty-hamburg.stefanimhoff.de.git" "url": "git+https://github.com/kogakure/website-11ty-hamburg.stefanimhoff.de.git"
}, },
"keywords": [ "keywords": [
"11ty" "11ty"
], ],
"author": "Stefan Imhoff", "author": "Stefan Imhoff",
"license": "ISC", "license": "ISC",
"homepage": "https://hamburg.stefanimhoff.de", "homepage": "https://hamburg.stefanimhoff.de",
"devDependencies": { "devDependencies": {
"@11ty/eleventy": "1.0.1", "@11ty/eleventy": "1.0.1",
"@11ty/eleventy-plugin-rss": "^1.1.1", "@11ty/eleventy-plugin-rss": "^1.1.1",
"autoprefixer": "^10.2.5", "autoprefixer": "^10.2.5",
"babelify": "^10.0.0", "babelify": "^10.0.0",
"browserify": "^17.0.0", "browserify": "^17.0.0",
"cssnano": "^5.0.2", "cssnano": "^5.0.2",
"del-cli": "^3.0.1", "del-cli": "^3.0.1",
"eleventy-nbsp-filter": "^0.1.0", "eleventy-nbsp-filter": "^0.1.0",
"eleventy-plugin-lazyimages": "^2.1.0", "eleventy-plugin-lazyimages": "^2.1.0",
"eslint": "^7.25.0", "eslint": "^7.25.0",
"eslint-config-prettier": "^8.3.0", "eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0", "eslint-plugin-prettier": "^3.4.0",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-imagemin": "^7.1.0", "gulp-imagemin": "^7.1.0",
"gulp-plumber": "^1.2.1", "gulp-plumber": "^1.2.1",
"gulp-postcss": "^9.0.0", "gulp-postcss": "^9.0.0",
"gulp-size": "^3.0.0", "gulp-size": "^3.0.0",
"gulp-sourcemaps": "^3.0.0", "gulp-sourcemaps": "^3.0.0",
"gulp-svg-sprite": "^1.5.0", "gulp-svg-sprite": "^1.5.0",
"html-minifier": "^4.0.0", "html-minifier": "^4.0.0",
"markdown-it-external-anchor": "^1.0.0", "markdown-it-external-anchor": "^1.0.0",
"markdown-it-footnote": "^3.0.2", "markdown-it-footnote": "^3.0.2",
"markdown-it-sub": "^1.0.0", "markdown-it-sub": "^1.0.0",
"markdown-it-sup": "^1.0.0", "markdown-it-sup": "^1.0.0",
"moment": "^2.29.1", "moment": "^2.29.1",
"netlify-cli": "^3.39.4", "netlify-cli": "^3.39.4",
"npm-run-all": "^4.1.5", "npm-run-all": "^4.1.5",
"outdent": "^0.8.0", "outdent": "^0.8.0",
"plop": "^2.7.4", "plop": "^2.7.4",
"postcss": "^8.2.13", "postcss": "^8.2.13",
"postcss-cli": "^8.3.1", "postcss-cli": "^8.3.1",
"postcss-custom-media": "^8.0.0", "postcss-custom-media": "^8.0.0",
"postcss-custom-properties": "^11.0.0", "postcss-custom-properties": "^11.0.0",
"postcss-extend": "^1.0.5", "postcss-extend": "^1.0.5",
"postcss-import": "^14.0.1", "postcss-import": "^14.0.1",
"postcss-media-minmax": "^5.0.0", "postcss-media-minmax": "^5.0.0",
"postcss-nested": "^5.0.5", "postcss-nested": "^5.0.5",
"postcss-sort-media-queries": "^3.8.9", "postcss-sort-media-queries": "^3.8.9",
"prettier": "^2.2.1", "prettier": "^2.2.1",
"sal.js": "^0.8.4", "sal.js": "^0.8.4",
"stylelint": "^13.13.0", "stylelint": "^13.13.0",
"stylelint-a11y": "^1.2.3", "stylelint-a11y": "^1.2.3",
"stylelint-config-prettier": "^8.0.2", "stylelint-config-prettier": "^8.0.2",
"stylelint-config-rational-order": "^0.1.2", "stylelint-config-rational-order": "^0.1.2",
"stylelint-config-recommended": "^5.0.0", "stylelint-config-recommended": "^5.0.0",
"stylelint-high-performance-animation": "^1.5.2", "stylelint-high-performance-animation": "^1.5.2",
"stylelint-order": "^4.1.0", "stylelint-order": "^4.1.0",
"stylelint-prettier": "^1.2.0", "stylelint-prettier": "^1.2.0",
"uglify-js": "^3.13.4", "uglify-js": "^3.13.4",
"vinyl-buffer": "^1.0.1", "vinyl-buffer": "^1.0.1",
"vinyl-source-stream": "^2.0.0", "vinyl-source-stream": "^2.0.0",
"workbox-cli": "^6.1.5" "workbox-cli": "^6.1.5"
}, },
"dependencies": {} "dependencies": {}
} }

View File

@@ -8,36 +8,36 @@ const date = moment().format();
const year = moment().format('YYYY'); const year = moment().format('YYYY');
module.exports = function (plop) { module.exports = function (plop) {
plop.setGenerator('District', { plop.setGenerator('District', {
description: 'Create a new district', description: 'Create a new district',
prompts: [ prompts: [
{ {
type: 'input', type: 'input',
name: 'title', name: 'title',
message: 'Title', message: 'Title',
validate(value) { validate(value) {
if (/.+/.test(value)) { if (/.+/.test(value)) {
return true; return true;
} }
return 'Title is required'; return 'Title is required';
}, },
}, },
], ],
actions() { actions() {
process.chdir(plop.getPlopfilePath()); process.chdir(plop.getPlopfilePath());
return [ return [
{ {
type: 'addMany', type: 'addMany',
destination: `${currentDir}/src/districts/`, destination: `${currentDir}/src/districts/`,
base: `${templatePath}`, base: `${templatePath}`,
templateFiles: '**/*.txt', templateFiles: '**/*.txt',
stripExtensions: ['txt'], stripExtensions: ['txt'],
data: { data: {
date, date,
}, },
}, },
]; ];
}, },
}); });
}; };

View File

@@ -1,13 +1,13 @@
module.exports = { module.exports = {
plugins: [ plugins: [
require('postcss-import'), require('postcss-import'),
require('postcss-custom-properties'), require('postcss-custom-properties'),
require('postcss-nested'), require('postcss-nested'),
require('postcss-extend'), require('postcss-extend'),
require('postcss-media-minmax'), require('postcss-media-minmax'),
require('postcss-custom-media'), require('postcss-custom-media'),
require('postcss-sort-media-queries')(), require('postcss-sort-media-queries')(),
require('autoprefixer'), require('autoprefixer'),
...(process.env.ELEVENTY_ENV === 'production' ? [require('cssnano')] : []), ...(process.env.ELEVENTY_ENV === 'production' ? [require('cssnano')] : []),
], ],
}; };

View File

@@ -1,5 +1,5 @@
window.addEventListener('load', () => { window.addEventListener('load', () => {
navigator.serviceWorker.register('/sw.js').catch((registrationError) => { navigator.serviceWorker.register('/sw.js').catch((registrationError) => {
console.error('SW registration failed: ', registrationError); console.error('SW registration failed: ', registrationError);
}); });
}); });

View File

@@ -1,42 +1,42 @@
(function () { (function () {
const root = document.getElementsByTagName('html')[0]; const root = document.getElementsByTagName('html')[0];
function setTheme(newTheme) { function setTheme(newTheme) {
window.__theme = newTheme; window.__theme = newTheme;
preferredTheme = newTheme; preferredTheme = newTheme;
const currentTheme = newTheme === 'light' ? 'dark' : 'light'; const currentTheme = newTheme === 'light' ? 'dark' : 'light';
root.classList.add(newTheme); root.classList.add(newTheme);
root.classList.remove(currentTheme); root.classList.remove(currentTheme);
} }
let preferredTheme; let preferredTheme;
try { try {
preferredTheme = localStorage.getItem('theme'); preferredTheme = localStorage.getItem('theme');
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
window.__setPreferredTheme = function (newTheme) { window.__setPreferredTheme = function (newTheme) {
setTheme(newTheme); setTheme(newTheme);
try { try {
localStorage.setItem('theme', newTheme); localStorage.setItem('theme', newTheme);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
} }
}; };
window.__toggleTheme = function () { window.__toggleTheme = function () {
const currentTheme = window.__theme; const currentTheme = window.__theme;
const newTheme = currentTheme === 'light' ? 'dark' : 'light'; const newTheme = currentTheme === 'light' ? 'dark' : 'light';
window.__setPreferredTheme(newTheme); window.__setPreferredTheme(newTheme);
}; };
const darkQuery = window.matchMedia('(prefers-color-scheme: dark)'); const darkQuery = window.matchMedia('(prefers-color-scheme: dark)');
darkQuery.addEventListener('change', function (e) { darkQuery.addEventListener('change', function (e) {
window.__setPreferredTheme(e.matches ? 'dark' : 'light'); window.__setPreferredTheme(e.matches ? 'dark' : 'light');
}); });
setTheme(preferredTheme || (darkQuery.matches ? 'dark' : 'light')); setTheme(preferredTheme || (darkQuery.matches ? 'dark' : 'light'));
})(); })();

View File

@@ -3,61 +3,57 @@ import { btnHandler } from './modules/btn-handler';
import { scrollHandler } from './modules/scroll-handler'; import { scrollHandler } from './modules/scroll-handler';
import { sourceCodeInfo } from './modules/source-code-info'; import { sourceCodeInfo } from './modules/source-code-info';
if ( if ('querySelector' in document && 'localStorage' in window && 'addEventListener' in window) {
'querySelector' in document && /* Initialize scroll reveal */
'localStorage' in window && sal({
'addEventListener' in window threshold: 0.1,
) { });
/* Initialize scroll reveal */
sal({
threshold: 0.1,
});
/* Show link to source code in console */ /* Show link to source code in console */
sourceCodeInfo(); sourceCodeInfo();
/* Scrolling up or down? */ /* Scrolling up or down? */
scrollHandler(); scrollHandler();
/* Toggle the theme */ /* Toggle the theme */
btnHandler('#theme-toggle', function () { btnHandler('#theme-toggle', function () {
window.__toggleTheme(); window.__toggleTheme();
}); });
/* Smooth scrolling to the top */ /* Smooth scrolling to the top */
btnHandler('#up-link', function () { btnHandler('#up-link', function () {
window.scroll({ window.scroll({
top: 0, top: 0,
left: 0, left: 0,
behavior: 'smooth', behavior: 'smooth',
}); });
}); });
btnHandler('.spoiler', function (event) { btnHandler('.spoiler', function (event) {
event.target.classList.toggle('spoiler-visible'); event.target.classList.toggle('spoiler-visible');
}); });
/* Deobfuscate the email */ /* Deobfuscate the email */
btnHandler( btnHandler(
'#email', '#email',
function (event) { function (event) {
if (event.target.classList.contains('objuscated')) { if (event.target.classList.contains('objuscated')) {
const link = event.target; const link = event.target;
const lock = link.parentNode.querySelector('#lock-box'); const lock = link.parentNode.querySelector('#lock-box');
event.preventDefault(); event.preventDefault();
link.classList.remove('objuscated'); link.classList.remove('objuscated');
link.text = 'hey@imhoff.name'; link.text = 'hey@imhoff.name';
link.href = 'mailto:hey@imhoff.name'; link.href = 'mailto:hey@imhoff.name';
if (lock) { if (lock) {
lock.classList.remove('hidden'); lock.classList.remove('hidden');
} }
} else { } else {
return; return;
} }
}, },
false false
); );
} }

View File

@@ -1,15 +1,15 @@
export function btnHandler(selector, callback, prevent = true) { export function btnHandler(selector, callback, prevent = true) {
const btn = document.querySelector(selector); const btn = document.querySelector(selector);
if (!btn) return; if (!btn) return;
btn.addEventListener( btn.addEventListener(
'click', 'click',
function (event) { function (event) {
if (prevent) { if (prevent) {
event.preventDefault(); event.preventDefault();
} }
callback(event); callback(event);
}, },
false false
); );
} }

View File

@@ -1,27 +1,24 @@
export function scrollHandler() { export function scrollHandler() {
const body = document.body; const body = document.body;
const scrollUp = 'scroll-up'; const scrollUp = 'scroll-up';
const scrollDown = 'scroll-down'; const scrollDown = 'scroll-down';
let lastScroll = 0; let lastScroll = 0;
window.addEventListener('scroll', () => { window.addEventListener('scroll', () => {
const currentScroll = window.pageYOffset; const currentScroll = window.pageYOffset;
if (currentScroll <= 0) { if (currentScroll <= 0) {
body.classList.remove(scrollUp); body.classList.remove(scrollUp);
return; return;
} }
if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) { if (currentScroll > lastScroll && !body.classList.contains(scrollDown)) {
body.classList.remove(scrollUp); body.classList.remove(scrollUp);
body.classList.add(scrollDown); body.classList.add(scrollDown);
} else if ( } else if (currentScroll < lastScroll && body.classList.contains(scrollDown)) {
currentScroll < lastScroll && body.classList.remove(scrollDown);
body.classList.contains(scrollDown) body.classList.add(scrollUp);
) { }
body.classList.remove(scrollDown); lastScroll = currentScroll;
body.classList.add(scrollUp); });
}
lastScroll = currentScroll;
});
} }

View File

@@ -1,6 +1,6 @@
export function sourceCodeInfo() { export function sourceCodeInfo() {
const sourceCodeInfo = const sourceCodeInfo =
'👋 I see youre interested in the source code of this site? You can find it here: https://github.com/kogakure/website-11ty-hamburg.stefanimhoff.de'; '👋 I see youre interested in the source code of this site? You can find it here: https://github.com/kogakure/website-11ty-hamburg.stefanimhoff.de';
console.info(sourceCodeInfo); console.info(sourceCodeInfo);
} }

View File

@@ -1,43 +1,43 @@
/* Colors */ /* Colors */
:root { :root {
--color-accent: #2d5da3; --color-accent: #2d5da3;
--color-bg-code: #282c34; --color-bg-code: #282c34;
--color-fg-code: #abb2bf; --color-fg-code: #abb2bf;
} }
:root, :root,
.light { .light {
--color-bg-full: #ffffff; --color-bg-full: #ffffff;
--color-bg: hsl(40, 7%, 90%); --color-bg: hsl(40, 7%, 90%);
--color-bg-dark: hsl(40, 7%, 80%); --color-bg-dark: hsl(40, 7%, 80%);
--color-border: rgb(185, 184, 182); --color-border: rgb(185, 184, 182);
--color-fg-feather-inverse: rgba(255, 255, 255, 0.05); --color-fg-feather-inverse: rgba(255, 255, 255, 0.05);
--color-fg-feather: rgba(0, 0, 0, 0.05); --color-fg-feather: rgba(0, 0, 0, 0.05);
--color-fg-full-inverse: #ffffff; --color-fg-full-inverse: #ffffff;
--color-fg-full: #000000; --color-fg-full: #000000;
--color-fg-soft-inverse: rgba(255, 255, 255, 0.2); --color-fg-soft-inverse: rgba(255, 255, 255, 0.2);
--color-fg-soft: rgba(0, 0, 0, 0.2); --color-fg-soft: rgba(0, 0, 0, 0.2);
--color-fg-strong-inverse: rgba(255, 255, 255, 0.8); --color-fg-strong-inverse: rgba(255, 255, 255, 0.8);
--color-fg-strong: rgba(0, 0, 0, 0.8); --color-fg-strong: rgba(0, 0, 0, 0.8);
--color-fg: hsl(40, 7%, 5%); --color-fg: hsl(40, 7%, 5%);
--opacity-dark: 1; --opacity-dark: 1;
--opacity-light: 0; --opacity-light: 0;
} }
.dark { .dark {
--color-bg-full: #000000; --color-bg-full: #000000;
--color-bg: hsl(40, 7%, 10%); --color-bg: hsl(40, 7%, 10%);
--color-bg-dark: hsl(40, 7%, 5%); --color-bg-dark: hsl(40, 7%, 5%);
--color-border: rgb(73, 72, 70); --color-border: rgb(73, 72, 70);
--color-fg-feather-inverse: rgba(0, 0, 0, 0.05); --color-fg-feather-inverse: rgba(0, 0, 0, 0.05);
--color-fg-feather: rgba(255, 255, 255, 0.05); --color-fg-feather: rgba(255, 255, 255, 0.05);
--color-fg-full-inverse: #000000; --color-fg-full-inverse: #000000;
--color-fg-full: #ffffff; --color-fg-full: #ffffff;
--color-fg-soft-inverse: rgba(0, 0, 0, 0.2); --color-fg-soft-inverse: rgba(0, 0, 0, 0.2);
--color-fg-soft: rgba(255, 255, 255, 0.2); --color-fg-soft: rgba(255, 255, 255, 0.2);
--color-fg-strong-inverse: rgba(0, 0, 0, 0.8); --color-fg-strong-inverse: rgba(0, 0, 0, 0.8);
--color-fg-strong: rgba(255, 255, 255, 0.8); --color-fg-strong: rgba(255, 255, 255, 0.8);
--color-fg: hsla(40, 7%, 90%, 0.87); --color-fg: hsla(40, 7%, 90%, 0.87);
--opacity-dark: 0; --opacity-dark: 0;
--opacity-light: 1; --opacity-light: 1;
} }

View File

@@ -1,17 +1,17 @@
@font-face { @font-face {
font-display: swap; font-display: swap;
font-family: 'SecuelaVariable'; font-family: 'SecuelaVariable';
font-style: normal; font-style: normal;
font-weight: 1 999; font-weight: 1 999;
src: url('/assets/fonts/secuela-regular-vf.woff2') format('woff2'), src: url('/assets/fonts/secuela-regular-vf.woff2') format('woff2'),
url('/assets/fonts/secuela-regular-vf.woff') format('woff'); url('/assets/fonts/secuela-regular-vf.woff') format('woff');
} }
@font-face { @font-face {
font-display: swap; font-display: swap;
font-family: 'SecuelaVariable'; font-family: 'SecuelaVariable';
font-style: italic; font-style: italic;
font-weight: 1 999; font-weight: 1 999;
src: url('/assets/fonts/secuela-italic-vf.woff2') format('woff2'), src: url('/assets/fonts/secuela-italic-vf.woff2') format('woff2'),
url('/assets/fonts/secuela-italic-vf.woff') format('woff'); url('/assets/fonts/secuela-italic-vf.woff') format('woff');
} }

View File

@@ -1,53 +1,53 @@
/** Image */ /** Image */
img { img {
background-color: var(--color-fg-feather); background-color: var(--color-fg-feather);
border-color: var(--color-fg-feather); border-color: var(--color-fg-feather);
border-radius: var(--radius-1); border-radius: var(--radius-1);
border-style: solid; border-style: solid;
border-width: 1px; border-width: 1px;
box-shadow: 0 2px 3px var(--color-fg-feather); box-shadow: 0 2px 3px var(--color-fg-feather);
display: block; display: block;
font-size: 0; font-size: 0;
height: auto; height: auto;
width: 100%; width: 100%;
} }
.dark img { .dark img {
opacity: 0.87; opacity: 0.87;
} }
img[src$='.svg'] { img[src$='.svg'] {
background: transparent; background: transparent;
border: 0; border: 0;
} }
.image-shadow { .image-shadow {
position: relative; position: relative;
transition-duration: 500ms; transition-duration: 500ms;
transition-property: transform; transition-property: transform;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
&::after { &::after {
box-shadow: var(--shadow-subtle-shade); box-shadow: var(--shadow-subtle-shade);
content: ''; content: '';
height: 100%; height: 100%;
left: 0; left: 0;
opacity: 0; opacity: 0;
position: absolute; position: absolute;
top: 0; top: 0;
transition-duration: 500ms; transition-duration: 500ms;
transition-property: opacity; transition-property: opacity;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
width: 100%; width: 100%;
z-index: -1; z-index: -1;
} }
&:hover, &:hover,
&:focus { &:focus {
transform: scale(1.03); transform: scale(1.03);
&::after { &::after {
opacity: 1; opacity: 1;
} }
} }
} }

View File

@@ -9,8 +9,8 @@
*/ */
html { html {
line-height: 1.15; /* 1 */ line-height: 1.15; /* 1 */
-webkit-text-size-adjust: 100%; /* 2 */ -webkit-text-size-adjust: 100%; /* 2 */
} }
/* Sections /* Sections
@@ -21,7 +21,7 @@ html {
*/ */
body { body {
margin: 0; margin: 0;
} }
/** /**
@@ -29,7 +29,7 @@ body {
*/ */
main { main {
display: block; display: block;
} }
/** /**
@@ -38,8 +38,8 @@ main {
*/ */
h1 { h1 {
font-size: 2em; font-size: 2em;
margin: 0.67em 0; margin: 0.67em 0;
} }
/* Grouping content /* Grouping content
@@ -51,9 +51,9 @@ h1 {
*/ */
hr { hr {
box-sizing: content-box; /* 1 */ box-sizing: content-box; /* 1 */
height: 0; /* 1 */ height: 0; /* 1 */
overflow: visible; /* 2 */ overflow: visible; /* 2 */
} }
/** /**
@@ -62,8 +62,8 @@ hr {
*/ */
pre { pre {
font-family: monospace, monospace; /* 1 */ font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */ font-size: 1em; /* 2 */
} }
/* Text-level semantics /* Text-level semantics
@@ -74,7 +74,7 @@ pre {
*/ */
a { a {
background-color: transparent; background-color: transparent;
} }
/** /**
@@ -83,9 +83,9 @@ a {
*/ */
abbr[title] { abbr[title] {
border-bottom: none; /* 1 */ border-bottom: none; /* 1 */
text-decoration: underline; /* 2 */ text-decoration: underline; /* 2 */
text-decoration: underline dotted; /* 2 */ text-decoration: underline dotted; /* 2 */
} }
/** /**
@@ -94,7 +94,7 @@ abbr[title] {
b, b,
strong { strong {
font-weight: bolder; font-weight: bolder;
} }
/** /**
@@ -105,8 +105,8 @@ strong {
code, code,
kbd, kbd,
samp { samp {
font-family: monospace, monospace; /* 1 */ font-family: monospace, monospace; /* 1 */
font-size: 1em; /* 2 */ font-size: 1em; /* 2 */
} }
/** /**
@@ -114,7 +114,7 @@ samp {
*/ */
small { small {
font-size: 80%; font-size: 80%;
} }
/** /**
@@ -124,18 +124,18 @@ small {
sub, sub,
sup { sup {
font-size: 75%; font-size: 75%;
line-height: 0; line-height: 0;
position: relative; position: relative;
vertical-align: baseline; vertical-align: baseline;
} }
sub { sub {
bottom: -0.25em; bottom: -0.25em;
} }
sup { sup {
top: -0.5em; top: -0.5em;
} }
/* Embedded content /* Embedded content
@@ -146,7 +146,7 @@ sup {
*/ */
img { img {
border-style: none; border-style: none;
} }
/* Forms /* Forms
@@ -162,10 +162,10 @@ input,
optgroup, optgroup,
select, select,
textarea { textarea {
font-family: inherit; /* 1 */ font-family: inherit; /* 1 */
font-size: 100%; /* 1 */ font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */ line-height: 1.15; /* 1 */
margin: 0; /* 2 */ margin: 0; /* 2 */
} }
/** /**
@@ -175,8 +175,8 @@ textarea {
button, button,
input { input {
/* 1 */ /* 1 */
overflow: visible; overflow: visible;
} }
/** /**
@@ -186,8 +186,8 @@ input {
button, button,
select { select {
/* 1 */ /* 1 */
text-transform: none; text-transform: none;
} }
/** /**
@@ -198,7 +198,7 @@ button,
[type='button'], [type='button'],
[type='reset'], [type='reset'],
[type='submit'] { [type='submit'] {
-webkit-appearance: button; -webkit-appearance: button;
} }
/** /**
@@ -209,8 +209,8 @@ button::-moz-focus-inner,
[type='button']::-moz-focus-inner, [type='button']::-moz-focus-inner,
[type='reset']::-moz-focus-inner, [type='reset']::-moz-focus-inner,
[type='submit']::-moz-focus-inner { [type='submit']::-moz-focus-inner {
border-style: none; border-style: none;
padding: 0; padding: 0;
} }
/** /**
@@ -221,7 +221,7 @@ button:-moz-focusring,
[type='button']:-moz-focusring, [type='button']:-moz-focusring,
[type='reset']:-moz-focusring, [type='reset']:-moz-focusring,
[type='submit']:-moz-focusring { [type='submit']:-moz-focusring {
outline: 1px dotted ButtonText; outline: 1px dotted ButtonText;
} }
/** /**
@@ -229,7 +229,7 @@ button:-moz-focusring,
*/ */
fieldset { fieldset {
padding: 0.35em 0.75em 0.625em; padding: 0.35em 0.75em 0.625em;
} }
/** /**
@@ -240,12 +240,12 @@ fieldset {
*/ */
legend { legend {
box-sizing: border-box; /* 1 */ box-sizing: border-box; /* 1 */
color: inherit; /* 2 */ color: inherit; /* 2 */
display: table; /* 1 */ display: table; /* 1 */
max-width: 100%; /* 1 */ max-width: 100%; /* 1 */
padding: 0; /* 3 */ padding: 0; /* 3 */
white-space: normal; /* 1 */ white-space: normal; /* 1 */
} }
/** /**
@@ -253,7 +253,7 @@ legend {
*/ */
progress { progress {
vertical-align: baseline; vertical-align: baseline;
} }
/** /**
@@ -261,7 +261,7 @@ progress {
*/ */
textarea { textarea {
overflow: auto; overflow: auto;
} }
/** /**
@@ -271,8 +271,8 @@ textarea {
[type='checkbox'], [type='checkbox'],
[type='radio'] { [type='radio'] {
box-sizing: border-box; /* 1 */ box-sizing: border-box; /* 1 */
padding: 0; /* 2 */ padding: 0; /* 2 */
} }
/** /**
@@ -281,7 +281,7 @@ textarea {
[type='number']::-webkit-inner-spin-button, [type='number']::-webkit-inner-spin-button,
[type='number']::-webkit-outer-spin-button { [type='number']::-webkit-outer-spin-button {
height: auto; height: auto;
} }
/** /**
@@ -290,8 +290,8 @@ textarea {
*/ */
[type='search'] { [type='search'] {
-webkit-appearance: textfield; /* 1 */ -webkit-appearance: textfield; /* 1 */
outline-offset: -2px; /* 2 */ outline-offset: -2px; /* 2 */
} }
/** /**
@@ -299,7 +299,7 @@ textarea {
*/ */
[type='search']::-webkit-search-decoration { [type='search']::-webkit-search-decoration {
-webkit-appearance: none; -webkit-appearance: none;
} }
/** /**
@@ -308,8 +308,8 @@ textarea {
*/ */
::-webkit-file-upload-button { ::-webkit-file-upload-button {
-webkit-appearance: button; /* 1 */ -webkit-appearance: button; /* 1 */
font: inherit; /* 2 */ font: inherit; /* 2 */
} }
/* Interactive /* Interactive
@@ -320,7 +320,7 @@ textarea {
*/ */
details { details {
display: block; display: block;
} }
/* /*
@@ -328,7 +328,7 @@ details {
*/ */
summary { summary {
display: list-item; display: list-item;
} }
/* Misc /* Misc
@@ -339,7 +339,7 @@ summary {
*/ */
template { template {
display: none; display: none;
} }
/** /**
@@ -347,5 +347,5 @@ template {
*/ */
[hidden] { [hidden] {
display: none; display: none;
} }

View File

@@ -2,17 +2,17 @@
/** Reset styles for Sal.js, if no JavaScript is available */ /** Reset styles for Sal.js, if no JavaScript is available */
.no-js { .no-js {
[data-sal|='fade'] { [data-sal|='fade'] {
opacity: 1; opacity: 1;
} }
[data-sal|='slide'], [data-sal|='slide'],
[data-sal|='zoom'] { [data-sal|='zoom'] {
opacity: 1; opacity: 1;
transform: none; transform: none;
} }
[data-sal|='flip'] { [data-sal|='flip'] {
transform: none; transform: none;
} }
} }

View File

@@ -1,28 +1,28 @@
/** Base */ /** Base */
html { html {
box-sizing: border-box; box-sizing: border-box;
font-size: 100%; font-size: 100%;
scroll-behavior: smooth; scroll-behavior: smooth;
} }
*, *,
*:before, *:before,
*:after { *:after {
box-sizing: inherit; box-sizing: inherit;
} }
::selection { ::selection {
background-color: #a3b387; background-color: #a3b387;
color: #ffffff; color: #ffffff;
} }
body { body {
background-color: var(--color-bg); background-color: var(--color-bg);
color: var(--color-fg); color: var(--color-fg);
font-family: var(--font-family-base); font-family: var(--font-family-base);
font-weight: var(--font-weight-normal); font-weight: var(--font-weight-normal);
height: 100vh; height: 100vh;
line-height: 1.6; line-height: 1.6;
} }
/** Headlines */ /** Headlines */
@@ -35,24 +35,24 @@ h6,
.page-title, .page-title,
.headline, .headline,
.subheadline { .subheadline {
font-weight: var(--font-weight-black); font-weight: var(--font-weight-black);
letter-spacing: -0.02em; letter-spacing: -0.02em;
line-height: var(--line-height-1); line-height: var(--line-height-1);
margin-block-start: 0; margin-block-start: 0;
position: relative; position: relative;
} }
h1, h1,
.page-title { .page-title {
font-size: var(--font-size-7); font-size: var(--font-size-7);
margin-block-end: var(--space-13); margin-block-end: var(--space-13);
} }
h2, h2,
.headline { .headline {
font-size: var(--font-size-5); font-size: var(--font-size-5);
margin-block-end: var(--space-10); margin-block-end: var(--space-10);
margin-block-start: var(--space-16); margin-block-start: var(--space-16);
} }
h3, h3,
@@ -60,9 +60,9 @@ h4,
h5, h5,
h6, h6,
.subheadline { .subheadline {
font-size: var(--font-size-4); font-size: var(--font-size-4);
margin-block-end: var(--space-8); margin-block-end: var(--space-8);
margin-block-start: var(--space-14); margin-block-start: var(--space-14);
} }
h2:first-of-type, h2:first-of-type,
@@ -70,7 +70,7 @@ h3:first-of-type,
h4:first-of-type, h4:first-of-type,
h5:first-of-type, h5:first-of-type,
h6:first-of-type { h6:first-of-type {
margin-block-start: 0; margin-block-start: 0;
} }
.dark h1, .dark h1,
@@ -82,133 +82,133 @@ h6:first-of-type {
.dark .title, .dark .title,
.dark .headline, .dark .headline,
.dark .subheadline { .dark .subheadline {
font-weight: var(--font-weight-extra-bold); font-weight: var(--font-weight-extra-bold);
} }
/** Paragraph */ /** Paragraph */
p, p,
.paragraph { .paragraph {
font-size: var(--font-size-3); font-size: var(--font-size-3);
font-weight: var(--font-weight-normal); font-weight: var(--font-weight-normal);
letter-spacing: normal; letter-spacing: normal;
line-height: var(--line-height-2); line-height: var(--line-height-2);
margin-block-end: var(--space-10); margin-block-end: var(--space-10);
margin-block-start: 0; margin-block-start: 0;
} }
p:last-of-type { p:last-of-type {
margin-block-end: 0; margin-block-end: 0;
} }
.dark p, .dark p,
.dark .paragraph { .dark .paragraph {
font-weight: var(--font-weight-light); font-weight: var(--font-weight-light);
} }
/** Lists */ /** Lists */
ul { ul {
font-size: var(--font-size-3); font-size: var(--font-size-3);
list-style-type: square; list-style-type: square;
margin-block-end: var(--space-12); margin-block-end: var(--space-12);
margin-block-start: 0; margin-block-start: 0;
padding-inline-start: 1.2em; padding-inline-start: 1.2em;
li { li {
margin-block-end: var(--space-5); margin-block-end: var(--space-5);
} }
li & { li & {
margin-block-end: 0; margin-block-end: 0;
padding-inline-start: 2rem; padding-inline-start: 2rem;
} }
} }
@media (--tablet) { @media (--tablet) {
ul { ul {
padding-inline-start: 0; padding-inline-start: 0;
} }
} }
ol { ol {
font-size: var(--font-size-3); font-size: var(--font-size-3);
margin-block-end: var(--space-12); margin-block-end: var(--space-12);
padding-inline-start: 1.2em; padding-inline-start: 1.2em;
li { li {
margin-block-end: var(--space-2); margin-block-end: var(--space-2);
} }
li & { li & {
margin-block-end: 0; margin-block-end: 0;
padding-inline-start: 2rem; padding-inline-start: 2rem;
} }
} }
@media (--tablet) { @media (--tablet) {
ol { ol {
padding-inline-start: 0; padding-inline-start: 0;
} }
} }
/** Critic Markup */ /** Critic Markup */
del { del {
text-decoration-thickness: 0.15em; text-decoration-thickness: 0.15em;
} }
ins { ins {
text-decoration-style: solid; text-decoration-style: solid;
text-decoration-thickness: 0.15em; text-decoration-thickness: 0.15em;
} }
mark { mark {
background-color: rgba(230, 240, 40, 0.7); background-color: rgba(230, 240, 40, 0.7);
border-color: rgba(0, 0, 0, 0.1); border-color: rgba(0, 0, 0, 0.1);
border-radius: 0.25em; border-radius: 0.25em;
box-shadow: var(--shadow-dark-inset); box-shadow: var(--shadow-dark-inset);
color: rgba(0, 0, 0, 0.75); color: rgba(0, 0, 0, 0.75);
padding-block-end: 0.4em; padding-block-end: 0.4em;
padding-block-start: 0.4em; padding-block-start: 0.4em;
padding-inline-end: 0.3em; padding-inline-end: 0.3em;
padding-inline-start: 0.3em; padding-inline-start: 0.3em;
} }
/** Code, Sample, Abbreviation, Keyboard Shortcuts etc. */ /** Code, Sample, Abbreviation, Keyboard Shortcuts etc. */
pre { pre {
white-space: pre; white-space: pre;
} }
abbr { abbr {
font-variant: small-caps; font-variant: small-caps;
} }
:is(abbr, dfn) { :is(abbr, dfn) {
cursor: help; cursor: help;
} }
/** Links */ /** Links */
a { a {
color: var(--color-fg); color: var(--color-fg);
font-weight: var(--font-weight-semi-bold); font-weight: var(--font-weight-semi-bold);
text-decoration: underline; text-decoration: underline;
text-decoration-color: var(--color-fg-soft); text-decoration-color: var(--color-fg-soft);
text-decoration-thickness: 0.2em; text-decoration-thickness: 0.2em;
text-underline-offset: auto; text-underline-offset: auto;
&:hover, &:hover,
&:focus { &:focus {
text-decoration-color: var(--color-accent); text-decoration-color: var(--color-accent);
} }
sup.footnote-ref & { sup.footnote-ref & {
text-decoration: none; text-decoration: none;
} }
} }
/** Helper */ /** Helper */
.no-margin { .no-margin {
margin: 0 !important; margin: 0 !important;
} }
.hidden { .hidden {
display: none !important; display: none !important;
} }

View File

@@ -1,81 +1,81 @@
:root { :root {
/** Grids */ /** Grids */
--grid-fullsize: repeat(18, 1fr); --grid-fullsize: repeat(18, 1fr);
--grid-row: clamp(3rem, var(--space-55), 9rem); --grid-row: clamp(3rem, var(--space-55), 9rem);
/** Border Widths */ /** Border Widths */
--border-width-1: 1px; --border-width-1: 1px;
--border-width-10: 0.1em; --border-width-10: 0.1em;
--border-width-15: 0.15em; --border-width-15: 0.15em;
/** Font Families */ /** Font Families */
--font-family-base: SecuelaVariable, Arial, sans-serif; --font-family-base: SecuelaVariable, Arial, sans-serif;
--font-family-mono: Fira Code, Operator, Hasklig, Monoid, monospace; --font-family-mono: Fira Code, Operator, Hasklig, Monoid, monospace;
/** Font Sizes */ /** Font Sizes */
--font-size-1: 0.65em; --font-size-1: 0.65em;
--font-size-2: clamp(0.65rem, 0.8vw, 0.75rem); --font-size-2: clamp(0.65rem, 0.8vw, 0.75rem);
--font-size-3: clamp(1rem, 1.1vw, 1.25rem); --font-size-3: clamp(1rem, 1.1vw, 1.25rem);
--font-size-4: clamp(1.25rem, 1.8vw, 2rem); --font-size-4: clamp(1.25rem, 1.8vw, 2rem);
--font-size-5: clamp(1.5rem, 2.9vw, 3.25rem); --font-size-5: clamp(1.5rem, 2.9vw, 3.25rem);
--font-size-6: clamp(2.25rem, 4.7vw, 5.3rem); --font-size-6: clamp(2.25rem, 4.7vw, 5.3rem);
--font-size-7: clamp(3.3rem, 7.3vw, 8.5rem); --font-size-7: clamp(3.3rem, 7.3vw, 8.5rem);
--font-size-8: clamp(4.5rem, 12.2vw, 13.87rem); --font-size-8: clamp(4.5rem, 12.2vw, 13.87rem);
--font-size-9: clamp(5.5rem, 28.7vw, 22.43rem); --font-size-9: clamp(5.5rem, 28.7vw, 22.43rem);
/** Font Weights */ /** Font Weights */
--font-weight-thin: 100; --font-weight-thin: 100;
--font-weight-extra-light: 200; --font-weight-extra-light: 200;
--font-weight-light: 300; --font-weight-light: 300;
--font-weight-normal: 400; --font-weight-normal: 400;
--font-weight-medium: 500; --font-weight-medium: 500;
--font-weight-semi-bold: 600; --font-weight-semi-bold: 600;
--font-weight-bold: 700; --font-weight-bold: 700;
--font-weight-extra-bold: 800; --font-weight-extra-bold: 800;
--font-weight-black: 900; --font-weight-black: 900;
/** Line Heights */ /** Line Heights */
--line-height-1: 1; --line-height-1: 1;
--line-height-2: 1.6; --line-height-2: 1.6;
/** Radii */ /** Radii */
--radius-1: 2px; --radius-1: 2px;
--radius-2: 5px; --radius-2: 5px;
--radius-4: 8px; --radius-4: 8px;
--radius-25: 25px; --radius-25: 25px;
--radius-50: 50%; --radius-50: 50%;
/** Shadows */ /** Shadows */
--shadow-subtle-shade: 0 0 50px rgba(0, 0, 0, 0.2); --shadow-subtle-shade: 0 0 50px rgba(0, 0, 0, 0.2);
--shadow-beveled-keyboard: 0 1px 0 rgba(0, 0, 0, 0.2), inset 0 0 0 2px #ffffff; --shadow-beveled-keyboard: 0 1px 0 rgba(0, 0, 0, 0.2), inset 0 0 0 2px #ffffff;
--shadow-white-outline: 0 1px 0 #ffffff; --shadow-white-outline: 0 1px 0 #ffffff;
--shadow-dark-inset: inset 0 0 5px rgba(0, 0, 0, 0.15); --shadow-dark-inset: inset 0 0 5px rgba(0, 0, 0, 0.15);
/** Space */ /** Space */
--space-1: 0.335rem; --space-1: 0.335rem;
--space-2: clamp(0.335rem, 0.72vw, 0.402rem); --space-2: clamp(0.335rem, 0.72vw, 0.402rem);
--space-3: clamp(0.402rem, 0.86vw, 0.482rem); --space-3: clamp(0.402rem, 0.86vw, 0.482rem);
--space-4: clamp(0.482rem, 1.03vw, 0.579rem); --space-4: clamp(0.482rem, 1.03vw, 0.579rem);
--space-5: clamp(0.579rem, 1.24vw, 0.694rem); --space-5: clamp(0.579rem, 1.24vw, 0.694rem);
--space-6: clamp(0.694rem, 1.49vw, 0.833rem); --space-6: clamp(0.694rem, 1.49vw, 0.833rem);
--space-7: clamp(0.833rem, 1.78vw, 1rem); --space-7: clamp(0.833rem, 1.78vw, 1rem);
--space-8: clamp(1rem, 2.14vw, 1.2rem); --space-8: clamp(1rem, 2.14vw, 1.2rem);
--space-9: clamp(1.2rem, 2.57vw, 1.44rem); --space-9: clamp(1.2rem, 2.57vw, 1.44rem);
--space-10: clamp(1.44rem, 3.7vw, 1.728rem); --space-10: clamp(1.44rem, 3.7vw, 1.728rem);
--space-11: clamp(1.728rem, 3.7vw, 2.074rem); --space-11: clamp(1.728rem, 3.7vw, 2.074rem);
--space-12: clamp(2.074rem, 4.44vw, 2.488rem); --space-12: clamp(2.074rem, 4.44vw, 2.488rem);
--space-13: clamp(2.488rem, 5.32vw, 2.986rem); --space-13: clamp(2.488rem, 5.32vw, 2.986rem);
--space-14: clamp(2.986rem, 6.39vw, 3.583rem); --space-14: clamp(2.986rem, 6.39vw, 3.583rem);
--space-15: clamp(3.583rem, 7.67vw, 4.3rem); --space-15: clamp(3.583rem, 7.67vw, 4.3rem);
--space-16: clamp(4.3rem, 9.2vw, 5.16rem); --space-16: clamp(4.3rem, 9.2vw, 5.16rem);
--space-17: clamp(5.16rem, 11.04vw, 6.192rem); --space-17: clamp(5.16rem, 11.04vw, 6.192rem);
--space-18: clamp(6.192rem, 13.25vw, 7.43rem); --space-18: clamp(6.192rem, 13.25vw, 7.43rem);
--space-19: clamp(7.43rem, 15.9vw, 8.916rem); --space-19: clamp(7.43rem, 15.9vw, 8.916rem);
--space-20: clamp(8.916rem, 19.08vw, 10.699rem); --space-20: clamp(8.916rem, 19.08vw, 10.699rem);
--space-55: 5.55vw; --space-55: 5.55vw;
/** Transitions */ /** Transitions */
--transition-duration-1: 100ms; --transition-duration-1: 100ms;
--transition-duration-2: 200ms; --transition-duration-2: 200ms;
--transition-duration-5: 500ms; --transition-duration-5: 500ms;
} }

View File

@@ -1,14 +1,14 @@
/** Video */ /** Video */
.video-wrapper { .video-wrapper {
margin-block-end: var(--space-10); margin-block-end: var(--space-10);
padding-block-end: 56.25%; padding-block-end: 56.25%;
position: relative; position: relative;
} }
.video-wrapper iframe { .video-wrapper iframe {
height: 100%; height: 100%;
left: 0; left: 0;
position: absolute; position: absolute;
top: 0; top: 0;
width: 100%; width: 100%;
} }

View File

@@ -1,13 +1,13 @@
/** Divider */ /** Divider */
hr, hr,
.divider { .divider {
border-block-end-width: var(--border-width-1); border-block-end-width: var(--border-width-1);
border-block-start-width: 0; border-block-start-width: 0;
border-color: var(--color-fg-feather); border-color: var(--color-fg-feather);
border-inline-end-width: 0; border-inline-end-width: 0;
border-inline-start-width: 0; border-inline-start-width: 0;
border-style: solid; border-style: solid;
margin-block-end: var(--space-14); margin-block-end: var(--space-14);
margin-block-start: var(--space-14); margin-block-start: var(--space-14);
width: 100%; width: 100%;
} }

View File

@@ -3,19 +3,19 @@
/** Email */ /** Email */
.lock-box { .lock-box {
align-items: center; align-items: center;
background: transparent; background: transparent;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
display: inline-flex; display: inline-flex;
height: 20px; height: 20px;
justify-content: center; justify-content: center;
position: relative; position: relative;
top: 0.2em; top: 0.2em;
width: 25px; width: 25px;
} }
.lock-icon { .lock-icon {
fill: var(--color-fg); fill: var(--color-fg);
font-size: 1.2em; font-size: 1.2em;
} }

View File

@@ -1,48 +1,48 @@
/** Pagination */ /** Pagination */
.pagination { .pagination {
border-radius: 50%; border-radius: 50%;
position: fixed; position: fixed;
top: calc(50% - 20px); top: calc(50% - 20px);
} }
.pagination-start { .pagination-start {
left: 1rem; left: 1rem;
} }
.pagination-end { .pagination-end {
right: 1rem; right: 1rem;
} }
.pagination-container { .pagination-container {
align-items: center; align-items: center;
background-color: var(--color-fg-feather); background-color: var(--color-fg-feather);
border-radius: 50%; border-radius: 50%;
border-width: 0; border-width: 0;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
font-size: 16px; font-size: 16px;
height: 40px; height: 40px;
justify-content: center; justify-content: center;
outline: none; outline: none;
transition-duration: 500ms; transition-duration: 500ms;
transition-property: opacity; transition-property: opacity;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
width: 40px; width: 40px;
a:hover &, a:hover &,
a:focus & { a:focus & {
background-color: var(--color-fg-soft); background-color: var(--color-fg-soft);
} }
.scroll-up & { .scroll-up & {
opacity: 1; opacity: 1;
} }
.scroll-down & { .scroll-down & {
opacity: 0; opacity: 0;
} }
} }
.pagination-icon { .pagination-icon {
fill: var(--color-fg); fill: var(--color-fg);
} }

View File

@@ -2,63 +2,63 @@
/** District Hero */ /** District Hero */
.district-hero-container { .district-hero-container {
grid-column: 5 / -1; grid-column: 5 / -1;
grid-row: 1 / 3; grid-row: 1 / 3;
height: 100vh; height: 100vh;
object-fit: cover; object-fit: cover;
} }
@media (--tablet) { @media (--tablet) {
.district-hero-container { .district-hero-container {
grid-column: 6 / -1; grid-column: 6 / -1;
} }
} }
.district-hero { .district-hero {
border: 0; border: 0;
height: 100vh; height: 100vh;
object-fit: cover; object-fit: cover;
} }
/** District Title */ /** District Title */
.district-title { .district-title {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
grid-column: 3 / 5; grid-column: 3 / 5;
grid-row: 1 / 3; grid-row: 1 / 3;
justify-content: center; justify-content: center;
padding-inline-start: calc(var(--space-55) / 2); padding-inline-start: calc(var(--space-55) / 2);
transform: rotate(180deg); transform: rotate(180deg);
writing-mode: vertical-lr; writing-mode: vertical-lr;
& h2 { & h2 {
font-size: var(--font-size-4); font-size: var(--font-size-4);
margin-block: 0; margin-block: 0;
} }
} }
@media (--tablet) { @media (--tablet) {
.district-title { .district-title {
grid-column: 5 / 6; grid-column: 5 / 6;
} }
} }
/** District Content */ /** District Content */
.district-content { .district-content {
grid-column: 2 / -2; grid-column: 2 / -2;
grid-row: 3; grid-row: 3;
& img { & img {
margin-block-end: var(--space-12); margin-block-end: var(--space-12);
} }
& iframe { & iframe {
width: 100%; width: 100%;
} }
} }
@media (--tablet) { @media (--tablet) {
.district-content { .district-content {
grid-column: 6 / -6; grid-column: 6 / -6;
} }
} }

View File

@@ -2,120 +2,120 @@
/** Homepage Hero */ /** Homepage Hero */
.homepage-hero-container { .homepage-hero-container {
grid-column: 4 / -1; grid-column: 4 / -1;
grid-row: 1 / 3; grid-row: 1 / 3;
height: 100vh; height: 100vh;
object-fit: cover; object-fit: cover;
} }
@media (--tablet) { @media (--tablet) {
.homepage-hero-container { .homepage-hero-container {
grid-column: 6 / -1; grid-column: 6 / -1;
} }
} }
.homepage-hero { .homepage-hero {
border: 0; border: 0;
height: 100vh; height: 100vh;
object-fit: cover; object-fit: cover;
} }
/** Homepage Introduction */ /** Homepage Introduction */
.homepage-introduction { .homepage-introduction {
grid-column: 4 / -2; grid-column: 4 / -2;
grid-row: 3; grid-row: 3;
} }
@media (--tablet) { @media (--tablet) {
.homepage-introduction { .homepage-introduction {
grid-column: 6 / span 6; grid-column: 6 / span 6;
} }
} }
/** Homepage Statistics */ /** Homepage Statistics */
.homepage-statistics { .homepage-statistics {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
grid-column: 2 / -2; grid-column: 2 / -2;
justify-content: center; justify-content: center;
} }
@media (--tablet) { @media (--tablet) {
.homepage-statistics { .homepage-statistics {
grid-column: 12 / -2; grid-column: 12 / -2;
grid-row: 4; grid-row: 4;
} }
} }
.homepage-statistics-image-container { .homepage-statistics-image-container {
grid-column: 1 / -1; grid-column: 1 / -1;
} }
@media (--tablet) { @media (--tablet) {
.homepage-statistics-image-container { .homepage-statistics-image-container {
grid-column: 2 / 11; grid-column: 2 / 11;
grid-row: 4; grid-row: 4;
} }
} }
.homepage-statistics-image { .homepage-statistics-image {
object-fit: cover; object-fit: cover;
} }
.homepage-statistics-container { .homepage-statistics-container {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
} }
.homepage-statistics-item { .homepage-statistics-item {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
.homepage-statistics-key { .homepage-statistics-key {
order: -1; order: -1;
} }
.homepage-statistics-value { .homepage-statistics-value {
font-size: var(--font-size-5); font-size: var(--font-size-5);
font-weight: var(--font-weight-black); font-weight: var(--font-weight-black);
} }
/** Homepage Districts */ /** Homepage Districts */
.homepage-districts { .homepage-districts {
grid-column: 2 / -2; grid-column: 2 / -2;
grid-row: 6; grid-row: 6;
} }
@media (--tablet) { @media (--tablet) {
.homepage-districts { .homepage-districts {
grid-row: 5; grid-row: 5;
} }
} }
.homepage-districts-grid { .homepage-districts-grid {
display: grid; display: grid;
grid-gap: calc(var(--space-55) / 4); grid-gap: calc(var(--space-55) / 4);
grid-template-columns: repeat(auto-fill, minmax(270px, 1fr)); grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.homepage-districts-item { .homepage-districts-item {
margin-block-end: 0; margin-block-end: 0;
} }
.homepage-districts-item-link { .homepage-districts-item-link {
text-decoration: none; text-decoration: none;
} }
.homepage-districts-item-headline { .homepage-districts-item-headline {
font-size: var(--font-size-3); font-size: var(--font-size-3);
font-weight: var(--font-weight-normal); font-weight: var(--font-weight-normal);
margin-block-end: 0; margin-block-end: 0;
} }
.homepage-districts-item-image { .homepage-districts-item-image {
margin-block-end: var(--space-3); margin-block-end: var(--space-3);
} }

View File

@@ -1,67 +1,67 @@
/** Base */ /** Base */
.page-grid { .page-grid {
display: grid; display: grid;
grid-template-columns: var(--grid-fullsize); grid-template-columns: var(--grid-fullsize);
grid-template-rows: var(--grid-row) auto var(--grid-row); grid-template-rows: var(--grid-row) auto var(--grid-row);
min-height: 100vh; min-height: 100vh;
} }
.page-content { .page-content {
display: grid; display: grid;
grid-auto-rows: auto; grid-auto-rows: auto;
grid-column: 1 / -1; grid-column: 1 / -1;
grid-row: 1 / -1; grid-row: 1 / -1;
grid-template-columns: var(--grid-fullsize); grid-template-columns: var(--grid-fullsize);
grid-template-rows: var(--grid-row); grid-template-rows: var(--grid-row);
margin-block-end: var(--grid-row); margin-block-end: var(--grid-row);
row-gap: clamp(1.5rem, var(--space-55), 6rem); row-gap: clamp(1.5rem, var(--space-55), 6rem);
} }
.page-title { .page-title {
align-items: center; align-items: center;
display: flex; display: flex;
font-size: var(--font-size-4); font-size: var(--font-size-4);
grid-column: 1 / 3; grid-column: 1 / 3;
grid-row: 1 / 3; grid-row: 1 / 3;
justify-content: flex-end; justify-content: flex-end;
margin: 0; margin: 0;
padding-inline-end: calc(var(--space-55) / 2); padding-inline-end: calc(var(--space-55) / 2);
transform: rotate(180deg); transform: rotate(180deg);
writing-mode: vertical-lr; writing-mode: vertical-lr;
} }
@media (--tablet) { @media (--tablet) {
.page-title { .page-title {
grid-column: 1; grid-column: 1;
} }
} }
.page-title-link { .page-title-link {
font-weight: var(--font-weight-black); font-weight: var(--font-weight-black);
text-decoration: none; text-decoration: none;
} }
.svg-icons { .svg-icons {
left: -9999px; left: -9999px;
position: absolute; position: absolute;
top: -9999px; top: -9999px;
} }
/** Narrow */ /** Narrow */
.layout-narrow { .layout-narrow {
grid-column: 3 / -3; grid-column: 3 / -3;
grid-row: 1 / 3; grid-row: 1 / 3;
padding-block-start: calc(var(--space-55) / 2); padding-block-start: calc(var(--space-55) / 2);
} }
@media (--tablet) { @media (--tablet) {
.layout-narrow { .layout-narrow {
grid-column: 6 / -6; grid-column: 6 / -6;
} }
} }
@media (--desktop) { @media (--desktop) {
.layout-narrow { .layout-narrow {
grid-column: 7 / -7; grid-column: 7 / -7;
} }
} }

View File

@@ -1,43 +1,43 @@
/** Footnotes */ /** Footnotes */
.footnote-ref a { .footnote-ref a {
color: var(--color-accent); color: var(--color-accent);
font-weight: var(--font-weight-light); font-weight: var(--font-weight-light);
} }
.footnote-bracket { .footnote-bracket {
display: none; display: none;
} }
.footnote-backref { .footnote-backref {
color: var(--color-accent); color: var(--color-accent);
font-weight: var(--font-weight-light); font-weight: var(--font-weight-light);
text-decoration: none; text-decoration: none;
} }
.footnotes { .footnotes {
padding-left: 2rem; padding-left: 2rem;
position: relative; position: relative;
} }
.footnotes :target { .footnotes :target {
background-color: var(--color-fg-feather); background-color: var(--color-fg-feather);
padding: var(--space-5); padding: var(--space-5);
} }
.footnotes-list { .footnotes-list {
counter-reset: item; counter-reset: item;
list-style: none; list-style: none;
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
.footnote-item::before { .footnote-item::before {
content: counter(item); content: counter(item);
counter-increment: item; counter-increment: item;
font-size: smaller; font-size: smaller;
font-weight: var(--font-weight-black); font-weight: var(--font-weight-black);
left: 0; left: 0;
padding-top: 0.15rem; padding-top: 0.15rem;
position: absolute; position: absolute;
vertical-align: super; vertical-align: super;
} }

View File

@@ -1,38 +1,38 @@
/** Legal Links */ /** Legal Links */
.legal { .legal {
align-items: center; align-items: center;
display: flex; display: flex;
font-size: 12px; font-size: 12px;
grid-column: 1 / -3; grid-column: 1 / -3;
padding-inline-start: clamp(15px, 2.4vw, 50px); padding-inline-start: clamp(15px, 2.4vw, 50px);
} }
.legal-copyright { .legal-copyright {
font-size: 14px; font-size: 14px;
margin-inline-end: 0.25em; margin-inline-end: 0.25em;
position: relative; position: relative;
top: 1px; top: 1px;
} }
.legal-author { .legal-author {
letter-spacing: 0.05em; letter-spacing: 0.05em;
text-transform: uppercase; text-transform: uppercase;
} }
.legal-author-link { .legal-author-link {
color: var(--color-fg); color: var(--color-fg);
text-decoration: none; text-decoration: none;
&:hover, &:hover,
&:focus { &:focus {
text-decoration: underline; text-decoration: underline;
text-decoration-color: var(--color-accent); text-decoration-color: var(--color-accent);
text-decoration-thickness: 0.15em; text-decoration-thickness: 0.15em;
text-underline-offset: 0.1em; text-underline-offset: 0.1em;
} }
} }
.legal-bullet { .legal-bullet {
margin-inline-end: 0.25em; margin-inline-end: 0.25em;
margin-inline-start: 0.25em; margin-inline-start: 0.25em;
} }

View File

@@ -1,9 +1,9 @@
/** Page Footer */ /** Page Footer */
.page-footer { .page-footer {
display: grid; display: grid;
grid-column: 1 / -1; grid-column: 1 / -1;
grid-row: 3; grid-row: 3;
grid-template-columns: var(--grid-fullsize); grid-template-columns: var(--grid-fullsize);
grid-template-rows: clamp(3rem, var(--space-55), 9rem); grid-template-rows: clamp(3rem, var(--space-55), 9rem);
margin-block-start: clamp(1.5rem, var(--space-55), 4.5rem); margin-block-start: clamp(1.5rem, var(--space-55), 4.5rem);
} }

View File

@@ -1,12 +1,12 @@
/** Page Header */ /** Page Header */
.page-header { .page-header {
/* margin-block-end: clamp(1.5rem, var(--space-55), 4.5rem); */ /* margin-block-end: clamp(1.5rem, var(--space-55), 4.5rem); */
display: grid; display: grid;
grid-column: 1 / -1; grid-column: 1 / -1;
grid-row: 1; grid-row: 1;
grid-template-columns: var(--grid-fullsize); grid-template-columns: var(--grid-fullsize);
grid-template-rows: clamp(3rem, var(--space-55), 9rem); grid-template-rows: clamp(3rem, var(--space-55), 9rem);
z-index: 1; z-index: 1;
} }
/* .minimal-page-header { */ /* .minimal-page-header { */

View File

@@ -1,35 +1,35 @@
/** Theme Toggle */ /** Theme Toggle */
.no-js .theme-toggle { .no-js .theme-toggle {
display: none; display: none;
} }
.theme-toggle { .theme-toggle {
align-items: center; align-items: center;
align-self: center; align-self: center;
background: transparent; background: transparent;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
font-size: 0; font-size: 0;
grid-column: -2; grid-column: -2;
height: 40px; height: 40px;
justify-content: center; justify-content: center;
justify-self: center; justify-self: center;
outline: 0; outline: 0;
width: 40px; width: 40px;
} }
.theme-toggle-icon { .theme-toggle-icon {
fill: var(--color-fg); fill: var(--color-fg);
font-size: 12px; font-size: 12px;
height: 12px; height: 12px;
transition-duration: var(--transition-duration-5); transition-duration: var(--transition-duration-5);
transition-property: transform; transition-property: transform;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
width: 12px; width: 12px;
.theme-toggle:hover &, .theme-toggle:hover &,
.theme-toggle:focus & { .theme-toggle:focus & {
transform: scale(1.25); transform: scale(1.25);
} }
} }

View File

@@ -1,33 +1,33 @@
/** Up Link */ /** Up Link */
.up-link { .up-link {
align-self: center; align-self: center;
grid-column: -2; grid-column: -2;
justify-self: center; justify-self: center;
transition-duration: var(--transition-duration-5); transition-duration: var(--transition-duration-5);
transition-property: transform; transition-property: transform;
transition-timing-function: ease-in-out; transition-timing-function: ease-in-out;
&:hover, &:hover,
&:focus { &:focus {
transform: translate3D(0, -0.25rem, 0); transform: translate3D(0, -0.25rem, 0);
} }
} }
.up-link-button { .up-link-button {
align-items: center; align-items: center;
background: transparent; background: transparent;
border: 0; border: 0;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
font-size: 0; font-size: 0;
height: 40px; height: 40px;
justify-content: center; justify-content: center;
width: 40px; width: 40px;
} }
.up-link-icon { .up-link-icon {
fill: var(--color-fg); fill: var(--color-fg);
font-size: 20px; font-size: 20px;
height: 20px; height: 20px;
width: 20px; width: 20px;
} }

View File

@@ -1,20 +1,20 @@
@page { @page {
margin: 1cm 0cm; margin: 1cm 0cm;
} }
/* Show all content immediatly */ /* Show all content immediatly */
[data-sal|='fade'] { [data-sal|='fade'] {
opacity: 1; opacity: 1;
} }
[data-sal|='slide'], [data-sal|='slide'],
[data-sal|='zoom'] { [data-sal|='zoom'] {
opacity: 1; opacity: 1;
transform: none; transform: none;
} }
[data-sal|='flip'] { [data-sal|='flip'] {
transform: none; transform: none;
} }
/* Hide content from printing */ /* Hide content from printing */
@@ -22,36 +22,36 @@
.page-footer, .page-footer,
.theme-toggle, .theme-toggle,
.pagination { .pagination {
display: none; display: none;
} }
/* Images */ /* Images */
img { img {
border: 0; border: 0;
max-width: 1200px; max-width: 1200px;
} }
/* Links */ /* Links */
a { a {
color: #000000; color: #000000;
word-wrap: break-word; word-wrap: break-word;
} }
a::after { a::after {
content: ' (https://hamburg.stefanimhoff.de' attr(href) ')'; content: ' (https://hamburg.stefanimhoff.de' attr(href) ')';
font-size: 80%; font-size: 80%;
} }
a[href^='mailto:']::after { a[href^='mailto:']::after {
content: ' (' attr(href) ')'; content: ' (' attr(href) ')';
} }
a[href^='http://']::after, a[href^='http://']::after,
a[href^='https://']::after a[href^='https://']::after
{ {
content: ' (' attr(href) ')'; content: ' (' attr(href) ')';
} }
a[href^='#']::after { a[href^='#']::after {
display: none; display: none;
} }

View File

@@ -4,14 +4,14 @@ const duration = 800;
const easing = 'ease-out-sine'; const easing = 'ease-out-sine';
module.exports = { module.exports = {
isProduction: process.env.ELEVENTY_ENV === 'production', isProduction: process.env.ELEVENTY_ENV === 'production',
buildTime: new Date(), buildTime: new Date(),
title: 'Exploring Hamburg', title: 'Exploring Hamburg',
description: 'Street by Street, District by District', description: 'Street by Street, District by District',
url: 'https://hamburg.stefanimhoff.de', url: 'https://hamburg.stefanimhoff.de',
author: 'Stefan Imhoff', author: 'Stefan Imhoff',
twitter: '@kogakure', twitter: '@kogakure',
faviconPath: '/assets/images/branding/favicons/', faviconPath: '/assets/images/branding/favicons/',
animationDelay: `data-sal=${animation} data-sal-duration=${duration} data-sal-delay=${delay} data-sal-easing=${easing}`, animationDelay: `data-sal=${animation} data-sal-duration=${duration} data-sal-delay=${delay} data-sal-easing=${easing}`,
animation: `data-sal=${animation} data-sal-duration=${duration} data-sal-easing=${easing}`, animation: `data-sal=${animation} data-sal-duration=${duration} data-sal-easing=${easing}`,
}; };

View File

@@ -1,6 +1,6 @@
{ {
"layout": "district", "layout": "district",
"permalink": "/{{ page.fileSlug }}/", "permalink": "/{{ page.fileSlug }}/",
"tags": ["districts"], "tags": ["districts"],
"templateEngineOverride": "njk,md" "templateEngineOverride": "njk,md"
} }

View File

@@ -4,30 +4,32 @@ eleventyExcludeFromCollections: true
--- ---
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:webfeeds="http://webfeeds.org/rss/1.0"> <feed xmlns="http://www.w3.org/2005/Atom" xmlns:webfeeds="http://webfeeds.org/rss/1.0">
<title>{{ site.title }}</title> <title>{{ site.title }}</title>
<subtitle>{{ site.description }}</subtitle> <subtitle>{{ site.description }}</subtitle>
<link href="{{ site.url }}/index.xml" rel="self" type="application/atom+xml" /> <link href="{{ site.url }}/index.xml" rel="self" type="application/atom+xml"/>
<link href="{{ site.url }}" rel="alternate" type="text/html"/> <link href="{{ site.url }}" rel="alternate" type="text/html"/>
{% if collections.districts %} {% if collections.districts %}
<updated>{{ collections.districts | rssLastUpdatedDate }}</updated> <updated>{{ collections.districts | rssLastUpdatedDate }}</updated>
{% endif %} {% endif %}
<id>{{ site.url }}/</id> <id>{{ site.url }}/</id>
<author> <author>
<name>{{ site.author }}</name> <name>{{ site.author }}</name>
</author> </author>
{% include "feed-webfeeds.njk" %} {% include "feed-webfeeds.njk" %}
{%- for item in collections.districts | reverse -%} {%- for item in collections.districts | reverse -%}
{% set absolutePostUrl %}{{ item.url | url | absoluteUrl(site.url) }}{% endset %} {% set absolutePostUrl %}{{ item.url | url | absoluteUrl(site.url) }}{% endset %}
{%- if not item.data.draft -%} {%- if not item.data.draft -%}
<entry> <entry>
<title>{{ item.data.title }}</title> <title>{{ item.data.title }}</title>
<link href="{{ absolutePostUrl }}"/> <link href="{{ absolutePostUrl }}"/>
<updated>{{ item.date | rssDate }}</updated> <updated>{{ item.date | rssDate }}</updated>
<id>{{ absolutePostUrl }}</id> <id>{{ absolutePostUrl }}</id>
<content type="html"><![CDATA[ <content type="html">
<![CDATA[
{{ item.templateContent | htmlToAbsoluteUrls(absolutePostUrl) | safe }} {{ item.templateContent | htmlToAbsoluteUrls(absolutePostUrl) | safe }}
]]></content> ]]>
</entry> </content>
{%- endif -%} </entry>
{%- endfor -%} {%- endif -%}
{%- endfor -%}
</feed> </feed>

View File

@@ -1,19 +1,20 @@
<section class="homepage-districts"> <section class="homepage-districts">
<h3 class="homepage-districts-headline"> <h3 class="homepage-districts-headline">
Districts Districts
</h3> </h3>
<ul class="homepage-districts-grid"> <ul class="homepage-districts-grid">
{% for item in collections.districts | sortByTitle %} {% for item in collections.districts | sortByTitle %}
<li class="homepage-districts-item" {{ site.animation }}> <li class="homepage-districts-item" {{ site.animation }}>
<a class="homepage-districts-item-link" href="{{ item.url }}"> <a class="homepage-districts-item-link" href="{{ item.url }}">
<div class="image-shadow"> <div class="image-shadow">
<img src="/assets/images/districts/thumbnails/hamburg-{{ item.data.title | slugify }}-450px.jpg" class="homepage-districts-item-image" alt="#"> <img src="/assets/images/districts/thumbnails/hamburg-{{ item.data.title | slugify }}-450px.jpg" class="homepage-districts-item-image" alt="#">
</div> </div>
<h3 class="homepage-districts-item-headline"> <h3 class="homepage-districts-item-headline">
{{ item.data.title }} {{ item.data.title }}
</h3> </h3>
</a> </a>
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
</section> </section>

View File

@@ -1,12 +1,12 @@
<div class="image-shadow homepage-hero-container"> <div class="image-shadow homepage-hero-container">
<img <img
class="homepage-hero" class="homepage-hero"
sizes="(max-width: 1200px) 100vw, 1200px" sizes="(max-width: 1200px) 100vw, 1200px"
srcset="/assets/images/core/homepage-hero-300.jpg 300w, srcset="/assets/images/core/homepage-hero-300.jpg 300w,
/assets/images/core/homepage-hero-600.jpg 600w, /assets/images/core/homepage-hero-600.jpg 600w,
/assets/images/core/homepage-hero-1200.jpg 1200w, /assets/images/core/homepage-hero-1200.jpg 1200w,
/assets/images/core/homepage-hero.jpg 1800w" /assets/images/core/homepage-hero.jpg 1800w"
src="/assets/images/core/homepage-hero.jpg" src="/assets/images/core/homepage-hero.jpg"
alt="Feuerschiff" alt="Feuerschiff"
/> />
</div> </div>

View File

@@ -1,19 +1,20 @@
<section id="introduction" class="homepage-introduction" {{ site.animation }}> <section id="introduction" class="homepage-introduction" {{ site.animation }}>
<div class="wrap"> <div class="wrap">
<div> <div>
<div> <div>
<h3 class="homepage-introduction-headline"> <h3 class="homepage-introduction-headline">
About About
</h3> </h3>
</div> </div>
<div class="homepage-introduction-text"> <div class="homepage-introduction-text">
<p> <p>
After living in Hamburg for more than 10 years, and still only knowing a small part of the city, I decided in 2015 to explore every district completely. After living in Hamburg for more than 10 years, and still only knowing a small part of the city, I decided in 2015 to explore every district completely.
</p> </p>
<p> <p>
I travel with my camera and a map all 109 districts of Hamburg as complete as possible, mostly by foot. I travel with my camera and a map all 109 districts of Hamburg as complete as possible, mostly by foot.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
</section> </section>

View File

@@ -1,15 +1,15 @@
<div class="image-shadow homepage-statistics-image-container"> <div class="image-shadow homepage-statistics-image-container">
<img <img
class="homepage-statistics-image" class="homepage-statistics-image"
sizes="(max-width: 1200px) 100vw, 1200px" sizes="(max-width: 1200px) 100vw, 1200px"
srcset="/assets/images/core/map-300.jpg 300w, srcset="/assets/images/core/map-300.jpg 300w,
/assets/images/core/map-600.jpg 600w, /assets/images/core/map-600.jpg 600w,
/assets/images/core/map-1200.jpg 1200w, /assets/images/core/map-1200.jpg 1200w,
/assets/images/core/map.jpg 1800w" /assets/images/core/map.jpg 1800w"
src="/assets/images/core/map.jpg" src="/assets/images/core/map.jpg"
alt="Historical Map of Hamburg" alt="Historical Map of Hamburg"
{{ site.animation }} {{ site.animation }}
/> />
</div> </div>
{% set distance = 0 %} {% set distance = 0 %}
@@ -17,39 +17,39 @@
{% set count = 0 %} {% set count = 0 %}
{% for item in collections.districts %} {% for item in collections.districts %}
{% set distance = distance + item.data.distance %} {% set distance = distance + item.data.distance %}
{% set duration = duration + item.data.duration %} {% set duration = duration + item.data.duration %}
{% set count = loop.length %} {% set count = loop.length %}
{% endfor %} {% endfor %}
<section id="statistics" class="homepage-statistics" {{ site.animationDelay }}> <section id="statistics" class="homepage-statistics" {{ site.animationDelay }}>
<h3 class="homepage-statistics-headline"> <h3 class="homepage-statistics-headline">
Statistics Statistics
</h3> </h3>
<div class="homepage-statistics-container"> <div class="homepage-statistics-container">
<div class="homepage-statistics-item"> <div class="homepage-statistics-item">
<span class="homepage-statistics-value"> <span class="homepage-statistics-value">
{{ distance }} {{ distance }}
</span> </span>
<span class="homepage-statistics-key"> <span class="homepage-statistics-key">
Kilometers Kilometers
</span> </span>
</div> </div>
<div class="homepage-statistics-item"> <div class="homepage-statistics-item">
<span class="homepage-statistics-value"> <span class="homepage-statistics-value">
{{ (duration / 60) | round }} {{ (duration / 60) | round }}
</span> </span>
<span class="homepage-statistics-key"> <span class="homepage-statistics-key">
Hours Hours
</span> </span>
</div> </div>
<div class="homepage-statistics-item"> <div class="homepage-statistics-item">
<span class="homepage-statistics-value"> <span class="homepage-statistics-value">
{{ count }} {{ count }}
</span> </span>
<span class="homepage-statistics-key"> <span class="homepage-statistics-key">
Districts Districts
</span> </span>
</div> </div>
</div> </div>
</section> </section>

View File

@@ -1,5 +1,6 @@
<div class="svg-icons"> <div class="svg-icons">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="0" height="0"> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="0" height="0">
{% include "icons.svg" %} {% include "icons.svg" %}
</svg> </svg>
</div> </div>

View File

@@ -1,12 +1,12 @@
<div class="legal"> <div class="legal">
<span class="legal-copyright">© </span> <span class="legal-copyright">© </span>
<strong class="legal-author"> <strong class="legal-author">
<a class="legal-author-link" href="/imprint/">{{ site.author }}</a> <a class="legal-author-link" href="/imprint/">{{ site.author }}</a>
</strong> </strong>
<span class="legal-bullet"> / </span> <span class="legal-bullet"> / </span>
<span class="legal-year"> <span class="legal-year">
<time datetime="{{ site.buildTime | dateToISO }}"> <time datetime="{{ site.buildTime | dateToISO }}">
2016{{ site.buildTime | dateToFormat('YYYY') }} 2016{{ site.buildTime | dateToFormat('YYYY') }}
</time> </time>
</span> </span>
</div> </div>

View File

@@ -1,46 +1,46 @@
{%- set ogTitle -%} {%- set ogTitle -%}
{%- if page.url === "/" -%} {%- if page.url === "/" -%}
{{ site.author }} · {{ site.description }} {{ site.author }} · {{ site.description }}
{%- else -%} {%- else -%}
{{ title }} · {{ site.author }} {{ title }} · {{ site.author }}
{%- endif -%} {%- endif -%}
{%- endset -%} {%- endset -%}
{%- set ogDescription -%} {%- set ogDescription -%}
{%- if page.url === "/" -%} {%- if page.url === "/" -%}
{{ site.tagline }} {{ site.tagline }}
{%- else -%} {%- else -%}
{{ description or title }} {{ description or title }}
{%- endif -%} {%- endif -%}
{%- endset -%} {%- endset -%}
{%- set ogImage -%} {%- set ogImage -%}
{%- if og -%} {%- if og -%}
{{ site.url }}/assets/images/branding/og/{{ og }} {{ site.url }}/assets/images/branding/og/{{ og }}
{%- else -%} {%- else -%}
{{ site.url }}/assets/images/branding/og/banner.png {{ site.url }}/assets/images/branding/og/banner.png
{%- endif -%} {%- endif -%}
{%- endset -%} {%- endset -%}
<!-- Meta --> <!-- Meta -->
<meta name="author" content="{{ site.author }}" /> <meta name="author" content="{{ site.author }}"/>
<meta name="description" content="{{ ogDescription }}" /> <meta name="description" content="{{ ogDescription }}"/>
<meta name="theme-color" content="#e7e6e4" /> <meta name="theme-color" content="#e7e6e4"/>
<meta name="generator" content="{{ eleventy.generator }}" /> <meta name="generator" content="{{ eleventy.generator }}"/>
<!-- Open graph --> <!-- Open graph -->
<meta property="og:title" content="{{ ogTitle }}" /> <meta property="og:title" content="{{ ogTitle }}"/>
<meta property="og:url" content="{{ site.url }}{{ page.url }}" /> <meta property="og:url" content="{{ site.url }}{{ page.url }}"/>
<meta property="og:description" content="{{ ogDescription }}" /> <meta property="og:description" content="{{ ogDescription }}"/>
<meta property="og:type" content="article" /> <meta property="og:type" content="article"/>
<meta property="og:image" content="{{ ogImage }}"/> <meta property="og:image" content="{{ ogImage }}"/>
<meta property="og:image:width" content="1200" /> <meta property="og:image:width" content="1200"/>
<meta property="og:image:height" content="675" /> <meta property="og:image:height" content="675"/>
<!-- Twitter --> <!-- Twitter -->
<meta name="twitter:title" content="{{ ogTitle }}" /> <meta name="twitter:title" content="{{ ogTitle }}"/>
<meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:card" content="summary_large_image"/>
<meta name="twitter:site" content="{{ site.twitter }}" /> <meta name="twitter:site" content="{{ site.twitter }}"/>
<meta name="twitter:description" content="{{ ogDescription }}" /> <meta name="twitter:description" content="{{ ogDescription }}"/>
<meta name="twitter:image" content="{{ ogImage }}" /> <meta name="twitter:image" content="{{ ogImage }}"/>
<meta name="twitter:creator" content="{{ site.twitter }}" /> <meta name="twitter:creator" content="{{ site.twitter }}"/>

View File

@@ -1,4 +1,5 @@
<footer class="page-footer"> <footer class="page-footer">
{% include "legal.njk" %} {% include "legal.njk" %}
{% include "up-link.njk" %} {% include "up-link.njk" %}
</footer> </footer>

View File

@@ -1,3 +1,3 @@
<header class="page-header" role="banner"> <header class="page-header" role="banner">
{% include "theme-toggle.njk" %} {% include "theme-toggle.njk" %}
</header> </header>

View File

@@ -1,5 +1,6 @@
<div class="pagination-container"> <div class="pagination-container">
<svg class="pagination-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em"> <svg class="pagination-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em">
<use xlink:href="#arrow-left-s"></use> <use xlink:href="#arrow-left-s"></use>
</svg> </svg>
</div> </div>

View File

@@ -1,5 +1,6 @@
<div class="pagination-container"> <div class="pagination-container">
<svg class="pagination-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em"> <svg class="pagination-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em">
<use xlink:href="#arrow-right-s"></use> <use xlink:href="#arrow-right-s"></use>
</svg> </svg>
</div> </div>

View File

@@ -1,23 +1,23 @@
{% if previousPost %} {% if previousPost %}
<a <a
aria-label="{{ previousPost.data.title }}" aria-label="{{ previousPost.data.title }}"
class="pagination pagination-start" class="pagination pagination-start"
href="{{ previousPost.url }}" href="{{ previousPost.url }}"
rel="prev" rel="prev"
title="{{ previousPost.data.title }}" title="{{ previousPost.data.title }}"
> >
{% include "pagination-left-arrow.njk" %} {% include "pagination-left-arrow.njk" %}
</a> </a>
{% endif %} {% endif %}
{% if nextPost %} {% if nextPost %}
<a <a
aria-label="{{ nextPost.data.title }}" aria-label="{{ nextPost.data.title }}"
class="pagination pagination-end" class="pagination pagination-end"
href="{{ nextPost.url }}" href="{{ nextPost.url }}"
rel="next" rel="next"
title="{{ nextPost.data.title }}" title="{{ nextPost.data.title }}"
> >
{% include "pagination-right-arrow.njk" %} {% include "pagination-right-arrow.njk" %}
</a> </a>
{% endif %} {% endif %}

View File

@@ -1,2 +1,3 @@
<link rel="preload" href="{{ '/assets/fonts/secuela-regular-vf.woff2' | url }}" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="{{ '/assets/fonts/secuela-regular-vf.woff2' | url }}" as="font" type="font/woff2" crossorigin/>
<link rel="preload" href="{{ '/assets/fonts/secuela-italic-vf.woff2' | url }}" as="font" type="font/woff2" crossorigin /> <link rel="preload" href="{{ '/assets/fonts/secuela-italic-vf.woff2' | url }}" as="font" type="font/woff2" crossorigin/>

View File

@@ -1,5 +1,6 @@
{% if robots %} {% if robots %}
<meta name="robots" content="{{ robots }}" /> <meta name="robots" content="{{ robots }}"/>
{% else %} {% else %}
<meta name="robots" content="all" /> <meta name="robots" content="all"/>
{% endif %} {% endif %}

View File

@@ -1,7 +1,9 @@
{% set js %} {% set js %}
{% include "../assets/scripts/embedded/theme-switcher.js" %} {% include "../assets/scripts/embedded/theme-switcher.js" %}
{% if site.isProduction %} {% if site.isProduction %}
{% include "../assets/scripts/embedded/register-serviceworker.js" %} {% include "../assets/scripts/embedded/register-serviceworker.js" %}
{% endif %} {% endif %}
{% endset %} {% endset %}
<script>{{ js | jsmin | safe }}</script> <script>
{{ js | jsmin | safe }}
</script>

View File

@@ -1,28 +1,27 @@
{% if site.isProduction %} {% if site.isProduction %}
{% set criticalCSS %} {% set criticalCSS %}
{% include "critical/base.css" %} {% include "critical/base.css" %}
{% if css %} {% if css %}
{% include "critical/" + css %} {% include "critical/" + css %}
{% endif %} {% endif %}
{% endset %} {% endset %}
<style> <style>
{{ criticalCSS | safe }} {{criticalCSS | safe}}
</style> </style>
{% else %} {% else %}
<link rel="stylesheet" href="{{ '/assets/styles/base.css' | url }}" /> <link rel="stylesheet" href="{{ '/assets/styles/base.css' | url }}"/>
{% if css %} {% if css %}
<link rel="stylesheet" href="{{ '/assets/styles/' + css | url }}" /> <link rel="stylesheet" href="{{ '/assets/styles/' + css | url }}"/>
{% endif %} {% endif %}
{% endif %} {% endif %}
<link rel="stylesheet" href="{{ '/assets/styles/main.css' | url }}" media="print" onload="this.media='all'" /> <link rel="stylesheet" href="{{ '/assets/styles/main.css' | url }}" media="print" onload="this.media='all'"/>
<link rel="stylesheet" href="{{ '/assets/styles/print.css' | url }}" media="print" /> <link rel="stylesheet" href="{{ '/assets/styles/print.css' | url }}" media="print"/>
<noscript> <noscript>
<link rel="stylesheet" href="{{ '/assets/styles/main.css' | url }}" /> <link rel="stylesheet" href="{{ '/assets/styles/main.css' | url }}"/>
</noscript> </noscript>

View File

@@ -1,5 +1,5 @@
<button id="theme-toggle" class="theme-toggle" aria-label="Switch color theme"> <button id="theme-toggle" class="theme-toggle" aria-label="Switch color theme">
<svg class="theme-toggle-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em"> <svg class="theme-toggle-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em">
<use xlink:href="#circle"></use> <use xlink:href="#circle"></use>
</svg> </svg>
</button> </button>

View File

@@ -1,7 +1,7 @@
<a id="up-link" class="up-link" href="#top" onClick="{scrollToTop}"> <a id="up-link" class="up-link" href="#top" onClick="{scrollToTop}">
<button class="up-link-button" aria-label="Back to top"> <button class="up-link-button" aria-label="Back to top">
<svg class="up-link-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em"> <svg class="up-link-icon" aria-hidden="true" viewBox="0 0 24 24" width="1em" height="1em">
<use xlink:href="#arrow-up"></use> <use xlink:href="#arrow-up"></use>
</svg> </svg>
</button> </button>
</a> </a>

View File

@@ -1,35 +1,41 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" class="no-js"> <html lang="en" class="no-js">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1"/>
<title> <title>
{%- if page.url === "/" -%} {%- if page.url === "/" -%}
{{ site.title }} · {{ site.description }} | {{ site.author}} {{ site.title }} · {{ site.description }} | {{ site.author}}
{%- else -%} {%- else -%}
{{ title }} · {{ site.title }} | {{ site.author}} {{ title }} · {{ site.title }} | {{ site.author}}
{%- endif -%} {%- endif -%}
</title> </title>
<link rel="canonical" href="{{ site.url }}{{ page.url }}" /> <link rel="canonical" href="{{ site.url }}{{ page.url }}"/>
<script type="module"> <script type="module">
document.documentElement.classList.remove('no-js'); document
document.documentElement.classList.add('js'); .documentElement
</script> .classList
.remove('no-js');
document
.documentElement
.classList
.add('js');
</script>
{% include "scripts.njk" %} {% include "scripts.njk" %}
{% include "styles.njk" %} {% include "styles.njk" %}
{% include "favicons.njk" %} {% include "favicons.njk" %}
{% include "meta-tags.njk" %} {% include "meta-tags.njk" %}
{% include "preload.njk" %} {% include "preload.njk" %}
{% include "robots.njk" %} {% include "robots.njk" %}
{% include "feeds.njk" %} {% include "feeds.njk" %}
</head> </head>
<body {% if bodyClass %}class="{{ bodyClass }}"{% endif %}> <body {% if bodyClass %}class="{{ bodyClass }}"{% endif %}>
{% include "icon-sprites.njk" %} {% include "icon-sprites.njk" %}
{{ content | safe }} {{ content | safe }}
<script src="/assets/scripts/main.js" async></script> <script src="/assets/scripts/main.js" async></script>
</body> </body>
</html> </html>

View File

@@ -3,14 +3,14 @@ layout: base
--- ---
<section class="page-grid"> <section class="page-grid">
{% include "page-header.njk" %} {% include "page-header.njk" %}
<main class="page-content"> <main class="page-content">
<h1 class="page-title"> <h1 class="page-title">
<a href="/" class="page-title-link"> <a href="/" class="page-title-link">
Exploring Hamburg Exploring Hamburg
</a> </a>
</h1> </h1>
{{ content | safe }} {{ content | safe }}
</main> </main>
{% include "page-footer.njk" %} {% include "page-footer.njk" %}
</section> </section>

View File

@@ -7,16 +7,16 @@ css: district.css
{% set nextPost = collections.districts | sortByTitle | getNextCollectionItem(page) %} {% set nextPost = collections.districts | sortByTitle | getNextCollectionItem(page) %}
<div class="image-shadow district-hero-container"> <div class="image-shadow district-hero-container">
<img class="district-hero" src="/assets/images/hero/hamburg-{{ title | slugify }}.jpg" alt="{{ title }}"/> <img class="district-hero" src="/assets/images/hero/hamburg-{{ title | slugify }}.jpg" alt="{{ title }}"/>
</div> </div>
<div class="district-title"> <div class="district-title">
<h2>{{ title }}</h2> <h2>{{ title }}</h2>
<small>{{ distance }} km / {{ (duration / 60) | round }} hrs.</small> <small>{{ distance }} km / {{ (duration / 60) | round }} hrs.</small>
</div> </div>
<div class="district-content"> <div class="district-content">
{{ content | safe }} {{ content | safe }}
</div> </div>
{% include "pagination.njk" %} {% include "pagination.njk" %}

View File

@@ -3,5 +3,5 @@ layout: default
--- ---
<div class="layout-narrow"> <div class="layout-narrow">
{{ content | safe }} {{ content | safe }}
</div> </div>

View File

@@ -4,12 +4,12 @@ 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 item in collections.all -%} {%- for item in collections.all -%}
{%- if not item.data.excludeFromSitemap and item.url -%} {%- if not item.data.excludeFromSitemap and item.url -%}
<url> <url>
<loc>{{ site.url }}{{ item.url | url | absoluteUrl(meta.url) }}</loc> <loc>{{ site.url }}{{ item.url | url | absoluteUrl(meta.url) }}</loc>
<lastmod>{{ item.date | dateToFormat('yyyy-MM-DD') }}</lastmod> <lastmod>{{ item.date | dateToFormat('yyyy-MM-DD') }}</lastmod>
</url> </url>
{%- endif -%} {%- endif -%}
{%- endfor -%} {%- endfor -%}
</urlset> </urlset>

View File

@@ -1 +1 @@
google-site-verification: googleeac4fc886a6f9f8d.html google-site-verification: googleeac4fc886a6f9f8d.html

View File

@@ -1,15 +1,13 @@
const moment = require('moment'); const moment = require('moment');
module.exports = { module.exports = {
dateToFormat: function (date, format = 'MMMM Do, YYYY') { dateToFormat: function (date, format = 'MMMM Do, YYYY') {
return moment(date).format(format); return moment(date).format(format);
}, },
dateToISO: function (date) { dateToISO: function (date) {
return moment(date).format(); return moment(date).format();
}, },
sortByTitle: function (values) { sortByTitle: function (values) {
return values return values.slice().sort((a, b) => a.data.title.localeCompare(b.data.title));
.slice() },
.sort((a, b) => a.data.title.localeCompare(b.data.title));
},
}; };

View File

@@ -1,15 +1,15 @@
const htmlmin = require('html-minifier'); const htmlmin = require('html-minifier');
module.exports = function (content, outputPath) { module.exports = function (content, outputPath) {
if (outputPath.endsWith('.html')) { if (outputPath.endsWith('.html')) {
let minified = htmlmin.minify(content, { let minified = htmlmin.minify(content, {
useShortDoctype: true, useShortDoctype: true,
removeComments: true, removeComments: true,
collapseWhitespace: true, collapseWhitespace: true,
}); });
return minified; return minified;
} }
return content; return content;
}; };

View File

@@ -1,12 +1,12 @@
const UglifyJS = require('uglify-js'); const UglifyJS = require('uglify-js');
module.exports = function (code) { module.exports = function (code) {
let minified = UglifyJS.minify(code); let minified = UglifyJS.minify(code);
if (minified.error) { if (minified.error) {
console.log('UglifyJS error: ', minified.error); console.log('UglifyJS error: ', minified.error);
return code; return code;
} }
return minified.code; return minified.code;
}; };

View File

@@ -1,15 +1,15 @@
const outdent = require('outdent')({ const outdent = require('outdent')({
newline: ' ', newline: ' ',
}); });
module.exports = { module.exports = {
email: function (text, key = false) { email: function (text, key = false) {
const downloadText = 'Download public key (ProtonMail/GPG)'; const downloadText = 'Download public key (ProtonMail/GPG)';
const link = outdent` const link = outdent`
<a id="email" class="objuscated" href="mailto:hey (at) imhoff (dot) name"> <a id="email" class="objuscated" href="mailto:hey (at) imhoff (dot) name">
${text} ${text}
</a>`; </a>`;
const keyDownload = outdent` const keyDownload = outdent`
<span id="lock-box" class="lock-box hidden"> <span id="lock-box" class="lock-box hidden">
<a <a
title="${downloadText}" title="${downloadText}"
@@ -21,20 +21,20 @@ module.exports = {
</svg> </svg>
</a></span>`; </a></span>`;
return `${link} ${key ? keyDownload : ''}`; return `${link} ${key ? keyDownload : ''}`;
}, },
map: function (mid) { map: function (mid) {
return outdent` return outdent`
<iframe class="map" src="https://www.google.com/maps/d/u/0/embed?mid=${mid}" width="1000" height="500"> <iframe class="map" src="https://www.google.com/maps/d/u/0/embed?mid=${mid}" width="1000" height="500">
</iframe>`; </iframe>`;
}, },
youtube: function (id) { youtube: function (id) {
return outdent` return outdent`
<div class="video-wrapper"> <div class="video-wrapper">
<iframe src="https://www.youtube.com/embed/${id}" <iframe src="https://www.youtube.com/embed/${id}"
frameborder="0" allowfullscreen frameborder="0" allowfullscreen
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"> allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture">
</iframe> </iframe>
</div>`; </div>`;
}, },
}; };

View File

@@ -4,22 +4,22 @@ permalink: manifest.webmanifest
ignore: true ignore: true
--- ---
{ {
"name": "{{ site.title }}", "name": "{{ site.title }}",
"short_name": "{{ site.title }}", "short_name": "{{ site.title }}",
"start_url": "/", "start_url": "/",
"icons": [ "icons": [
{ {
"src": "{{ site.faviconPath }}favicon-192.png", "src": "{{ site.faviconPath }}favicon-192.png",
"sizes": "192x192", "sizes": "192x192",
"type": "image/png" "type": "image/png"
}, },
{ {
"src": "{{ site.faviconPath }}favicon-512.png", "src": "{{ site.faviconPath }}favicon-512.png",
"sizes": "512x512", "sizes": "512x512",
"type": "image/png" "type": "image/png"
} }
], ],
"theme_color": "#e7e6e4", "theme_color": "#e7e6e4",
"background_color": "#e7e6e4", "background_color": "#e7e6e4",
"display": "standalone" "display": "standalone"
} }

View File

@@ -1,22 +1,22 @@
module.exports = { module.exports = {
globDirectory: 'dist/', globDirectory: 'dist/',
globPatterns: ['**/*.woff2'], globPatterns: ['**/*.woff2'],
swDest: 'dist/sw.js', swDest: 'dist/sw.js',
sourcemap: false, sourcemap: false,
cleanupOutdatedCaches: true, cleanupOutdatedCaches: true,
clientsClaim: true, clientsClaim: true,
skipWaiting: true, skipWaiting: true,
runtimeCaching: [ runtimeCaching: [
{ {
urlPattern: /\.(?:jpg|png|svg|gif|webp|avif)$/, urlPattern: /\.(?:jpg|png|svg|gif|webp|avif)$/,
handler: 'CacheFirst', handler: 'CacheFirst',
options: { options: {
cacheName: 'images', cacheName: 'images',
expiration: { expiration: {
maxEntries: 50, maxEntries: 50,
maxAgeSeconds: 60 * 60 * 24 * 365, maxAgeSeconds: 60 * 60 * 24 * 365,
}, },
}, },
}, },
], ],
}; };