shift asset processing to webpack (#424)

also migrated SASS to latest syntax (via dart-sass) and vastly simplified light/dark theme logic
This commit is contained in:
jake authored and GitHub committed 2021-06-19 17:19:01 -04:00
1 parent 622432c3e4
commit 363b4edf1c
105 files changed
+4061 -955

No files matched your search

+1 -1
View File
@@ -46,5 +46,5 @@
"es6": true
}
}],
"ignorePatterns": ["public/**", "postcss.config.js"]
"ignorePatterns": ["public/**", "postcss.config.js", "gulpfile.js", "webpack.config.js"]
}
+2 -2
View File
@@ -34,8 +34,8 @@ jobs:
node-version: 14.x
- name: Install dependencies
run: yarn install --frozen-lockfile
- name: Build preview
run: yarn build:hugo --environment=development --baseURL=/ --buildDrafts --buildFuture
- name: Build site
run: yarn build
- name: Percy snapshots
uses: percy/snapshot-action@v0.1.2
env:
+1
View File
@@ -16,6 +16,7 @@ jobs:
with:
fetch-depth: 0
- uses: getsentry/action-release@v1
if: github.event.deployment_status.environment == 'production'
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: jakejarvis
+4
View File
@@ -4,6 +4,10 @@ builds/
_vendor/
hugo_stats.json
# webpack artifacts
data/manifest.json
static/assets/
# node/npm/yarn
node_modules/
package-lock.json
+1
View File
@@ -20,6 +20,7 @@
"unused-javascript": "warn",
"uses-optimized-images": "warn",
"uses-rel-preconnect": "warn",
"canonical": "off",
"is-crawlable": "off",
"modern-image-formats": "off",
"offscreen-images": "off",
+3
View File
@@ -3,6 +3,7 @@ assets/**/vendor/
layouts/
static/
hugo_stats.json
data/manifest.json
# output from Hugo
public/
@@ -13,6 +14,8 @@ _vendor/
# dotfiles/config
.*
postcss.config.js
webpack.config.js
gulpfile.js
babel.config.json
tsconfig.json
+1
View File
@@ -10,6 +10,7 @@
"rules": {
"color-hex-length": "long",
"max-nesting-depth": 6,
"order/order": null,
"order/properties-alphabetical-order": null,
"plugin/no-unsupported-browser-features": [true, {
"severity": "warning",
+6 -1
View File
@@ -2,7 +2,12 @@
# https://github.com/jakejarvis/hugo-docker/blob/master/Dockerfile
FROM ghcr.io/jakejarvis/hugo-extended:0.83.1
ADD package.json .
ADD yarn.lock .
RUN yarn install
# expose live-refresh server (on custom port)
EXPOSE 1337
CMD ["server", "--disableFastRender", "--buildDrafts", "--buildFuture", "--port=1337", "--baseURL=/", "--appendPort=false", "--bind=0.0.0.0", "--verbose"]
ENTRYPOINT ["yarn"]
CMD ["start"]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

+3 -3
View File
@@ -1,4 +1,4 @@
/*! Copyright Twitter Inc. and other contributors. Licensed under MIT *//*
/* Copyright Twitter Inc. and other contributors. Licensed under MIT *//*
https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
*/
@@ -12,7 +12,7 @@
/////////////////////////
// default assets url, by default will be Twitter Inc. CDN
base: '/vendor/emoji/',
base: '/assets/emoji/',
// default assets file extensions, by default '.png'
ext: '.svg',
@@ -265,7 +265,7 @@
* @return string the image source to use
*/
function defaultImageSrcGenerator(icon, options) {
return ''.concat(options.base, options.size, '/', icon, options.ext);
return ''.concat(options.base, icon, options.ext);
}
/**
+18 -43
View File
@@ -1,4 +1,7 @@
@charset "UTF-8";
@use "sass:math";
@use "sass:string";
@use "settings";
// Gradient hack to get our custom underline to wrap:
// https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/
@@ -10,16 +13,24 @@
// Less compatible but better for light/dark mode switching.
// We fall back to non-alpha hex colors with postcss-color-rgba-fallback to mitigate this.
$color-opaque-alpha: rgba($color, $link-underline-opacity / 100%);
$color-opaque-alpha: rgba($color, math.div(settings.$link-underline-opacity, 100%));
// Return non-gradient linear-gradient():
@return linear-gradient($color-opaque-alpha, $color-opaque-alpha);
}
// Web fonts (see components/_typography.scss)
@mixin font-face($family, $src, $weight: normal, $style: normal, $display: swap, $variable: false) {
@mixin font-face(
$family,
$src,
$weight: normal,
$style: normal,
$display: swap,
$variable: false,
$base-path: "../fonts/"
) {
@font-face {
font-family: $family;
font-family: string.quote($family);
font-style: $style;
font-weight: $weight;
font-display: $display;
@@ -27,49 +38,13 @@
@if $variable {
// all browsers that support variable fonts also support woff2, so a woff file is unncessary
// draft spec for formats: https://www.w3.org/TR/css-fonts-4/#src-desc
src: url($base-url + $src + ".woff2") format("woff2-variations"), url($base-url + $src + ".woff2") format("woff2");
src: url($base-path + $src + ".woff2") format("woff2-variations"),
url($base-path + $src + ".woff2") format("woff2");
} @else {
src: url($base-url + $src + ".woff2") format("woff2"), url($base-url + $src + ".woff") format("woff");
src: url($base-path + $src + ".woff2") format("woff2"), url($base-path + $src + ".woff") format("woff");
}
// Allow additional rules to be passed in:
@content;
}
}
// Simple dark/light theme switching via <body> class and $themes map in abstracts/_themes.scss
// https://medium.com/@katiemctigue/how-to-create-a-dark-mode-in-sass-609f131a3995
//
// Note: ONLY color rules should go in here (eg: just `border-color`, not the whole `border` rule)
$theme-map: (); // now declaring global variables this way: https://sass-lang.com/documentation/variables#scope
@mixin colors() {
@each $theme, $map in $themes {
body.#{$theme} & {
@each $key, $submap in $map {
$value: map-get(map-get($themes, $theme), "#{$key}");
$theme-map: map-merge(
$theme-map,
(
$key: $value,
)
) !global;
}
@content;
}
}
}
// Just @include colors() and call c() when a rule depends on which theme is active.
// The argument is a key in the $themes array in abstracts/_themes.
//
// img {
// border: 1px solid;
//
// @include colors() {
// border-color: c(medium-dark); // ONLY the color rules here.
// }
// }
//
@function c($key) {
@return map-get($theme-map, $key);
}
-3
View File
@@ -1,3 +0,0 @@
@charset "UTF-8";
@import "modern-normalize/modern-normalize.css";
+24 -12
View File
@@ -1,16 +1,28 @@
@charset "UTF-8";
@use "../abstracts/settings";
@use "../components/global";
@use "../components/header";
@use "../components/footer";
@use "../components/content";
@use "../pages/home";
@use "../pages/list";
@use "../pages/single";
@use "../pages/videos";
@use "../pages/etc";
@use "../pages/projects";
// Responsive Awesomeness
@media screen and (max-width: $responsive-width) {
@include responsive--global();
@include responsive--header();
@include responsive--footer();
@include responsive--content();
@media screen and (max-width: settings.$responsive-width) {
@include global.responsive();
@include header.responsive();
@include footer.responsive();
@include content.responsive();
@include responsive--home();
@include responsive--list();
@include responsive--single();
@include responsive--videos();
@include responsive--etc();
@include responsive--projects();
@include home.responsive();
@include list.responsive();
@include single.responsive();
@include videos.responsive();
@include etc.responsive();
@include projects.responsive();
}
+3 -3
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
// Web fonts
$webfont-sans: "Inter";
$webfont-sans-variable: "Inter var";
@@ -17,7 +15,9 @@ $font-stack-variable: $webfont-sans-variable, $system-fonts-sans;
$font-stack-mono: $webfont-mono, $system-fonts-monospace;
$font-stack-mono-variable: $webfont-mono-variable, $system-fonts-monospace;
// Width at which to switch to mobile styles
// The maximum width of the content area:
$max-width: 865px;
// Width at which to switch to mobile styles:
$responsive-width: 800px;
// Fancy link underline settings
+11 -1
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "sass:map";
// Dark & Light Themes
$themes: (
@@ -161,3 +161,13 @@ $icon-bulb-on: 'data:image/svg+xml;charset=utf-8,<svg viewBox="0 0 22 35" xmlns=
$icon-bulb-off: 'data:image/svg+xml;charset=utf-8,<svg viewBox="0 0 22 35" xmlns="http://www.w3.org/2000/svg"><g fill-rule="nonzero" fill="none"><path d="M22 11.06c0 6.44-5 7.44-5 13.44 0 3.1-3.12 3.36-5.5 3.36-2.05 0-6.59-.78-6.59-3.36 0-6-4.91-7-4.91-13.44C0 5.03 5.29.14 11.08.14 16.88.14 22 5.03 22 11.06z" fill="#CCCBCB"/><path d="M15.17 32.5c0 .83-2.24 2.5-4.17 2.5-1.93 0-4.17-1.67-4.17-2.5 0-.83 2.24-.5 4.17-.5 1.93 0 4.17-.33 4.17.5z" fill="#CCD6DD"/><path d="M15.7 10.3a1 1 0 00-1.4 0L11 13.58l-3.3-3.3a1 1 0 10-1.4 1.42l3.7 3.7V26a1 1 0 102 0V15.41l3.7-3.7a1 1 0 000-1.42z" fill="#7D7A72"/><path d="M17 31a2 2 0 01-2 2H7a2 2 0 01-2-2v-6h12v6z" fill="#99AAB5"/><path d="M5 32a1 1 0 01-.16-1.99l12-2a1 1 0 11.33 1.97l-12 2A.93.93 0 015 32zm0-4a1 1 0 01-.16-1.99l12-2a1 1 0 11.33 1.97l-12 2A.93.93 0 015 28z" fill="#CCD6DD"/></g></svg>';
$icon-wand: 'data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 36 36"><g fill="none"><path fill="#292F33" d="M2.651 6.073l26.275 26.276c.391.391 2.888-2.107 2.497-2.497L5.148 3.576c-.39-.391-2.888 2.107-2.497 2.497z"/><path fill="#66757F" d="M29.442 31.23L3.146 4.934l.883-.883 26.296 26.296z"/><path fill="#E1E8ED" d="M33.546 33.483l-.412.412-.671.671a.967.967 0 01-.255.169.988.988 0 01-1.159-.169l-2.102-2.102.495-.495.883-.883 1.119-1.119 2.102 2.102a.999.999 0 010 1.414zM4.029 4.79l-.883.883-.495.495L.442 3.96a.988.988 0 01-.169-1.159.967.967 0 01.169-.255l.671-.671.412-.412a.999.999 0 011.414 0l2.208 2.208L4.029 4.79z"/><path fill="#F5F8FA" d="M30.325 30.497l2.809 2.809-.671.671a.967.967 0 01-.255.169l-2.767-2.767.884-.882zM3.146 5.084L.273 2.211a.967.967 0 01.169-.255l.671-.671 2.916 2.916-.883.883z"/><path fill="#FFAC33" d="M27.897 10.219l1.542.571.6 2.2a.667.667 0 001.287 0l.6-2.2 1.542-.571a.665.665 0 000-1.25l-1.534-.568-.605-2.415a.667.667 0 00-1.293 0l-.605 2.415-1.534.568a.665.665 0 000 1.25m-16.936 9.628l2.61.966.966 2.61a1.103 1.103 0 002.07 0l.966-2.61 2.609-.966a1.103 1.103 0 000-2.07l-2.609-.966-.966-2.61a1.105 1.105 0 00-2.07 0l-.966 2.61-2.61.966a1.104 1.104 0 000 2.07M23.13 4.36l1.383.512.512 1.382a.585.585 0 001.096 0l.512-1.382 1.382-.512a.584.584 0 000-1.096l-1.382-.512-.512-1.382a.585.585 0 00-1.096 0l-.512 1.382-1.383.512a.585.585 0 000 1.096"/></g></svg>';
// ----------------------------------------
@mixin themed($property, $key) {
@each $theme, $map in $themes {
@at-root body.#{$theme} #{&} {
#{$property}: map-get($map, $key);
}
}
}
+4 -6
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
/*! Magic Waving Hand Emoji™: https://jrvs.io/wave */
.wave {
@@ -6,14 +6,14 @@
animation: wave 5s infinite;
animation-delay: 1s;
transform-origin: 65% 80%;
will-change: transform; // stylelint-disable-line plugin/no-unsupported-browser-features
will-change: transform;
}
.beat {
display: inline-block;
animation: beat 10s infinite; // 6 bpm, call 911 if you see this please.
animation-delay: 7.5s; // offset from wave animation
will-change: transform; // stylelint-disable-line plugin/no-unsupported-browser-features
will-change: transform;
}
// modified from https://tobiasahlin.com/spinkit/
@@ -28,9 +28,7 @@
display: inline-block;
animation: loader 1.4s infinite ease-in-out both;
@include colors() {
background-color: c(medium-light);
}
@include themes.themed(background-color, "medium-light");
}
.spin-bounce1 {
+4 -8
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
div#content {
font-size: 0.925em;
@@ -19,9 +19,7 @@ div#content {
padding-bottom: 0.25em;
border-bottom: 1px solid;
@include colors() {
border-color: c(kinda-light);
}
@include themes.themed(border-color, "kinda-light");
}
p.center {
@@ -43,9 +41,7 @@ div#content {
line-height: 1.5;
margin-top: 0.5em;
@include colors() {
color: c(medium);
}
@include themes.themed(color, "medium");
}
}
@@ -61,6 +57,6 @@ div#content {
}
// Responsive
@mixin responsive--content() {
@mixin responsive() {
// stylelint-disable-block block-no-empty
}
-2
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
div.embed {
&.tweet {
.twitter-tweet-rendered iframe {
+8 -13
View File
@@ -1,4 +1,5 @@
@charset "UTF-8";
@use "../abstracts/settings";
@use "../abstracts/themes";
// Global Footer Styles
footer {
@@ -7,21 +8,17 @@ footer {
padding: 1.25em 1.5em;
border-top: 1px solid;
@include colors() {
color: c(medium-dark);
border-color: c(kinda-light);
}
@include themes.themed(color, "medium-dark");
@include themes.themed(border-color, "kinda-light");
a {
@include colors() {
color: c(medium-dark);
}
@include themes.themed(color, "medium-dark");
}
div.row {
display: flex;
width: 100%;
max-width: $max-width;
max-width: settings.$max-width;
margin: 0 auto;
justify-content: space-between;
font-size: 0.85em;
@@ -33,14 +30,12 @@ footer {
padding-bottom: 2px;
border-bottom: 1px solid;
@include colors() {
border-color: c(light);
}
@include themes.themed(border-color, "light");
}
}
// Responsive
@mixin responsive--footer() {
@mixin responsive() {
footer {
padding: 1em 1.25em 0 1.25em;
+58 -43
View File
@@ -1,4 +1,8 @@
@charset "UTF-8";
@use "sass:map";
@use "../abstracts/functions";
@use "../abstracts/settings";
@use "../abstracts/themes";
// Global Styles
body {
@@ -7,27 +11,47 @@ body {
margin: 0 auto;
scroll-behavior: smooth;
font-family: settings.$font-stack-sans;
font-kerning: normal;
font-variant-ligatures: normal;
font-feature-settings: "kern", "liga", "calt", "clig", "ss01";
// global base font size:
font-size: 0.975em;
}
line-height: 1.5;
// manually setting light/dark mode backgrounds and bulb icon
// really just the color of header & footer
body {
&.light {
background-color: map-get(map-get($themes, "light"), "background-outer");
button.dark-mode-toggle {
background-image: url($icon-bulb-on);
}
// set themed lightbulb icons manually
&.light button.dark-mode-toggle {
background-image: url(themes.$icon-bulb-on);
}
&.dark {
background-color: map-get(map-get($themes, "dark"), "background-outer");
&.dark button.dark-mode-toggle {
background-image: url(themes.$icon-bulb-off);
}
}
button.dark-mode-toggle {
background-image: url($icon-bulb-off);
}
code,
pre,
.monospace {
font-family: settings.$font-stack-mono;
letter-spacing: normal;
}
// need to set light/dark mode backgrounds outside of the body selector
@include themes.themed(background-color, "background-outer");
// override above font-family if browser supports variable fonts
// https://caniuse.com/#feat=variable-fonts
@supports (font-variation-settings: normal) {
body {
font-family: settings.$font-stack-variable;
font-optical-sizing: auto;
}
code,
pre,
.monospace {
font-family: settings.$font-stack-mono-variable;
}
}
@@ -36,36 +60,37 @@ main {
width: 100%;
padding: 0 1.5em;
@include colors() {
background-color: c(background-inner);
color: c(text);
}
@include themes.themed(color, "text");
@include themes.themed(background-color, "background-inner");
}
// this is what's extended by different layouts (in ../pages)
div.layout {
max-width: $max-width;
max-width: settings.$max-width;
margin: 0 auto;
display: block; // https://stackoverflow.com/questions/28794718/max-width-not-working-for-ie-11
}
// cool link underlines:
// https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/
a {
text-decoration: none;
background-position: 0% 100%;
background-repeat: no-repeat;
background-size: 0% $link-underline-size;
padding-bottom: $link-underline-size;
background-size: 0% settings.$link-underline-size;
padding-bottom: settings.$link-underline-size;
transition: background-size 0.25s ease-in-out;
@include colors() {
color: c(links);
background-image: underline-hack(c(links));
@include themes.themed(color, "links");
// cool link underlines (via messy SCSS hacking):
// https://www.dannyguo.com/blog/animated-multiline-link-underlines-with-css/
@each $theme, $map in themes.$themes {
@at-root body.#{$theme} #{&} {
background-image: functions.underline-hack(map-get($map, "links"));
}
}
&:hover {
background-size: 100% $link-underline-size;
background-size: 100% settings.$link-underline-size;
}
&.no-underline {
@@ -79,21 +104,13 @@ strong {
letter-spacing: 0.008em; // not sure why the discrepancy between weights
}
code,
pre,
.monospace {
letter-spacing: normal;
}
blockquote {
margin-left: 0;
padding-left: 1.5em;
border-left: 3px solid;
@include colors() {
color: c(medium-dark);
border-color: c(links);
}
@include themes.themed(color, "medium-dark");
@include themes.themed(border-color, "links");
}
hr {
@@ -101,9 +118,7 @@ hr {
height: 2px;
border: 0;
@include colors() {
background-color: c(light);
}
@include themes.themed(background-color, "light");
}
// make SVG twemojis relative to surrounding text
@@ -126,7 +141,7 @@ a img.emoji {
}
// Responsive
@mixin responsive--global() {
@mixin responsive() {
body {
// Safari iOS menu bar reappears below 44px:
// https://www.eventbrite.com/engineering/mobile-safari-why/
+11 -22
View File
@@ -1,4 +1,5 @@
@charset "UTF-8";
@use "../abstracts/settings";
@use "../abstracts/themes";
// Global Header Styles
header {
@@ -6,13 +7,11 @@ header {
padding: 0.7em 1.5em;
border-bottom: 1px solid;
@include colors() {
border-color: c(kinda-light);
}
@include themes.themed(border-color, "kinda-light");
nav {
width: 100%;
max-width: $max-width;
max-width: settings.$max-width;
margin: 0 auto;
display: flex;
align-items: center;
@@ -22,9 +21,7 @@ header {
display: flex;
align-items: center;
@include colors() {
color: c(medium-dark);
}
@include themes.themed(color, "medium-dark");
img#selfie {
width: 50px;
@@ -32,9 +29,7 @@ header {
border: 1px solid;
border-radius: 50%;
@include colors() {
border-color: c(light);
}
@include themes.themed(border-color, "light");
}
span#name {
@@ -45,9 +40,7 @@ header {
}
&:hover {
@include colors() {
color: c(links);
}
@include themes.themed(color, "links");
img#selfie {
opacity: 0.9;
@@ -70,18 +63,14 @@ header {
a {
display: inline-block;
transition: transform 0.15s ease-in-out;
will-change: transform; // stylelint-disable-line plugin/no-unsupported-browser-features
will-change: transform;
@include colors() {
color: c(medium-dark);
}
@include themes.themed(color, "medium-dark");
&:hover {
transform: scale(1.1);
@include colors() {
color: c(links);
}
@include themes.themed(color, "links");
}
span.icon {
@@ -128,7 +117,7 @@ header {
}
// Responsive
@mixin responsive--header() {
@mixin responsive() {
header {
padding: 0.5em 1.25em;
+185
View File
@@ -0,0 +1,185 @@
// stylelint-disable
/*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
/*
Document
========
*/
/**
Use a better box model (opinionated).
*/
*,
::before,
::after {
box-sizing: border-box;
}
/**
1. Correct the line height in all browsers.
2. Use a more readable tab size (opinionated).
3. Prevent adjustments of font size after orientation changes in iOS.
*/
html {
line-height: 1.15; /* 1 */
tab-size: 4; /* 2 */
-webkit-text-size-adjust: 100%; /* 3 */
}
/*
Sections
========
*/
/*
Grouping content
================
*/
/**
1. Add the correct height in Firefox.
2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
*/
hr {
height: 0; /* 1 */
color: inherit; /* 2 */
}
/*
Text-level semantics
====================
*/
/**
Add the correct text decoration in Chrome, Edge, and Safari.
*/
abbr[title] {
text-decoration: underline dotted;
}
/**
Add the correct font weight in Edge and Safari.
*/
b,
strong {
font-weight: bolder;
}
/**
Correct the odd 'em' font sizing in all browsers.
*/
code,
kbd,
samp,
pre {
font-size: 1em;
}
/**
Add the correct font size in all browsers.
*/
small {
font-size: 80%;
}
/**
Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
/*
Tabular data
============
*/
/**
1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
*/
table {
text-indent: 0; /* 1 */
border-color: inherit; /* 2 */
}
/*
Forms
=====
*/
/**
1. Change the font styles in all browsers.
2. Remove the margin in Firefox and Safari.
*/
button,
input,
optgroup,
select,
textarea {
font-family: inherit; /* 1 */
font-size: 100%; /* 1 */
line-height: 1.15; /* 1 */
margin: 0; /* 2 */
}
/**
Remove the inheritance of text transform in Edge and Firefox.
*/
button,
select {
text-transform: none;
}
/**
Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
*/
legend {
padding: 0;
}
/**
Add the correct vertical alignment in Chrome and Firefox.
*/
progress {
vertical-align: baseline;
}
/*
Interactive
===========
*/
/*
Add the correct display in Chrome and Safari.
*/
summary {
display: list-item;
}
-2
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
// all code
code {
font-size: 0.925em;
+25 -41
View File
@@ -1,4 +1,5 @@
@charset "UTF-8";
@use "../abstracts/functions";
@use "../abstracts/settings";
// Note to self: got this list after subsetting Inter with glyphhanger or pyftsubset:
// https://github.com/filamentgroup/glyphhanger
@@ -16,30 +17,30 @@ $unicode-subset: U+0000-00FF, U+2000-206F, U+2200-22FF, U+2122;
*/
// Variable
@include font-face("Inter var", "vendor/fonts/inter-subset.var", 100 900, $variable: true) {
@include functions.font-face("Inter var", "inter-subset.var", 100 900, $variable: true) {
unicode-range: $unicode-subset;
}
@include font-face("Inter var", "vendor/fonts/inter-italic-subset.var", 100 900, italic, $variable: true) {
@include functions.font-face("Inter var", "inter-italic-subset.var", 100 900, italic, $variable: true) {
unicode-range: $unicode-subset;
}
// Legacy
@include font-face("Inter", "vendor/fonts/inter-regular-subset", 400) {
@include functions.font-face("Inter", "inter-regular-subset", 400) {
unicode-range: $unicode-subset;
}
@include font-face("Inter", "vendor/fonts/inter-regular-italic-subset", 400, italic) {
@include functions.font-face("Inter", "inter-regular-italic-subset", 400, italic) {
unicode-range: $unicode-subset;
}
@include font-face("Inter", "vendor/fonts/inter-medium-subset", 500) {
@include functions.font-face("Inter", "inter-medium-subset", 500) {
unicode-range: $unicode-subset;
}
@include font-face("Inter", "vendor/fonts/inter-medium-italic-subset", 500, italic) {
@include functions.font-face("Inter", "inter-medium-italic-subset", 500, italic) {
unicode-range: $unicode-subset;
}
@include font-face("Inter", "vendor/fonts/inter-bold-subset", 700) {
@include functions.font-face("Inter", "inter-bold-subset", 700) {
unicode-range: $unicode-subset;
}
@include font-face("Inter", "vendor/fonts/inter-bold-italic-subset", 700, italic) {
@include functions.font-face("Inter", "inter-bold-italic-subset", 700, italic) {
unicode-range: $unicode-subset;
}
@@ -52,40 +53,23 @@ $unicode-subset: U+0000-00FF, U+2000-206F, U+2200-22FF, U+2122;
*/
// Variable
@include font-face("Roboto Mono var", "vendor/fonts/roboto-mono-subset.var", 100 700, $variable: true);
@include font-face("Roboto Mono var", "vendor/fonts/roboto-mono-italic-subset.var", 100 700, italic, $variable: true);
@include functions.font-face("Roboto Mono var", "roboto-mono-subset.var", 100 700, $variable: true);
@include functions.font-face("Roboto Mono var", "roboto-mono-italic-subset.var", 100 700, italic, $variable: true);
// Legacy
@include font-face("Roboto Mono", "vendor/fonts/roboto-mono-regular-subset", 400);
@include font-face("Roboto Mono", "vendor/fonts/roboto-mono-italic-subset", 400, italic);
@include functions.font-face("Roboto Mono", "roboto-mono-regular-subset", 400);
@include functions.font-face("Roboto Mono", "roboto-mono-italic-subset", 400, italic);
/* --------- */
body {
font-family: $font-stack-sans;
font-kerning: normal;
font-variant-ligatures: normal;
font-feature-settings: "kern", "liga", "calt", "clig", "ss01";
line-height: 1.5;
/*!
* Comic Neue typeface v2.5 - http://comicneue.com/
*
* Copyright (c) 2014 The Comic Neue Project Authors.
* Licensed under the SIL Open Font License, Version 1.1:
* https://github.com/crozynski/comicneue/blob/v2.5/OFL.txt
*/
@include functions.font-face("Comic Neue", "comic-neue-regular-subset", 400) {
unicode-range: U+0000-00FF, U+2000-206F, U+20A0-20CF, U+2190-21FF, U+2200-22FF, U+2122;
}
code,
pre,
.monospace {
font-family: $font-stack-mono;
}
// override above font-family if browser supports variable fonts
// https://caniuse.com/#feat=variable-fonts
@supports (font-variation-settings: normal) {
body {
font-family: $font-stack-variable;
font-optical-sizing: auto;
}
code,
pre,
.monospace {
font-family: $font-stack-mono-variable;
}
@include functions.font-face("Comic Neue", "comic-neue-bold-subset", 700) {
unicode-range: U+0000-00FF, U+2000-206F, U+20A0-20CF, U+2190-21FF, U+2200-22FF, U+2122;
}
+18 -33
View File
@@ -1,40 +1,25 @@
@charset "UTF-8";
// NOTE: all variables set by Hugo's config.toml MUST go here:
// prettier-ignore
$max-width: "{{ printf "%d%s" .Site.Params.Theme.maxWidth "px" }}";
$base-url: "{{ strings.TrimRight "/" .Site.BaseURL }}" + "/";
// those values need quotes because, even though prettier & stylelint are correct
// in that it's insanely invalid SCSS, they refuse to ignore it. but $max-width is
// a numerical value that can't have quotes, so let's remove them...
$max-width: unquote($max-width);
// Variables & Functions
@import "abstracts/functions";
@import "abstracts/settings";
@import "abstracts/themes";
@import "abstracts/reset";
// Global Styles
@import "components/typography";
@import "components/global";
@import "components/header";
@import "components/footer";
@import "components/content";
@import "components/embeds";
@use "components/typography";
@use "components/reset";
@use "components/global";
@use "components/header";
@use "components/footer";
@use "components/content";
@use "components/embeds";
// Pages
@import "pages/home";
@import "pages/list";
@import "pages/single";
@import "pages/videos";
@import "pages/etc";
@import "pages/projects";
// Responsive Mixins
@import "abstracts/responsive";
@use "pages/home";
@use "pages/list";
@use "pages/single";
@use "pages/videos";
@use "pages/etc";
@use "pages/projects";
// Miscellaneous
@import "components/syntax";
@import "components/animation";
@use "components/syntax";
@use "components/animation";
// Responsive Mixins
@use "abstracts/responsive";
+1 -3
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
// Video Styles
div.layout-etc {
padding-top: 1.5em;
@@ -17,7 +15,7 @@ div.layout-etc {
}
// Responsive
@mixin responsive--etc() {
@mixin responsive() {
div.layout-etc {
h1 {
font-size: 1.6em;
+9 -10
View File
@@ -1,4 +1,5 @@
@charset "UTF-8";
@use "../abstracts/functions";
@use "../abstracts/themes";
// Home Styles
div.layout-home {
@@ -52,20 +53,18 @@ div.layout-home {
// easter egg emoji cursor
a#birthday {
&:hover {
cursor: url($icon-wand) 0 0, auto;
cursor: url(themes.$icon-wand) 0 0, auto;
}
}
// non-link colors
span {
&#serverless {
color: $color-serverless;
color: themes.$color-serverless;
}
&#shh {
@include colors() {
color: c(medium-light);
}
@include themes.themed(color, "medium-light");
}
&.wave {
@@ -75,17 +74,17 @@ div.layout-home {
}
// Loop through $colors-home (see abstracts/_variables)
@each $id, $colors in $colors-home {
@each $id, $colors in themes.$colors-home {
@each $theme, $color in $colors {
body.#{$theme} div.layout-home a##{$id} {
@at-root body.#{$theme} div.layout-home a##{$id} {
color: $color;
background-image: underline-hack($color);
background-image: functions.underline-hack($color);
}
}
}
// Responsive
@mixin responsive--home() {
@mixin responsive() {
div.layout-home {
font-size: 0.975em;
padding-top: 1em;
+3 -5
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
// Archive/List Styles
div.layout-list {
@@ -32,9 +32,7 @@ div.layout-list {
width: 5.25em;
flex-shrink: 0;
@include colors() {
color: c(medium);
}
@include themes.themed(color, "medium");
}
&:last-child {
@@ -45,7 +43,7 @@ div.layout-list {
}
// Responsive
@mixin responsive--list() {
@mixin responsive() {
div.layout-list {
padding-top: 1em;
padding-bottom: 0;
+5 -9
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
// Video Styles
div.layout-projects {
@@ -38,10 +38,8 @@ div.layout-projects {
border-radius: 6px;
font-size: 0.9em;
@include colors() {
color: c(medium-dark);
border-color: c(kinda-light);
}
@include themes.themed(color, "medium-dark");
@include themes.themed(border-color, "kinda-light");
a.repo-name {
font-size: 1.2em;
@@ -57,9 +55,7 @@ div.layout-projects {
margin-right: 12px;
font-size: 0.925em;
@include colors() {
color: c(medium);
}
@include themes.themed(color, "medium");
svg {
display: inline-block;
@@ -84,7 +80,7 @@ div.layout-projects {
}
// Responsive
@mixin responsive--projects() {
@mixin responsive() {
div.layout-projects {
// stylelint-disable-block block-no-empty
}
+4 -8
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
// Post Styles
div.layout-single {
@@ -11,9 +11,7 @@ div.layout-single {
letter-spacing: 0.04em;
margin-top: 0.3em;
@include colors() {
color: c(medium);
}
@include themes.themed(color, "medium");
a {
color: inherit;
@@ -47,9 +45,7 @@ div.layout-single {
content: "#"; // cosmetically hashtagify tags
padding-right: 0.125em;
@include colors() {
color: c(light);
}
@include themes.themed(color, "light");
}
&:last-of-type {
@@ -75,7 +71,7 @@ div.layout-single {
}
// Responsive
@mixin responsive--single() {
@mixin responsive() {
div.layout-single {
padding-top: 0.8em;
padding-bottom: 0.4em;
+3 -5
View File
@@ -1,4 +1,4 @@
@charset "UTF-8";
@use "../abstracts/themes";
// Video Styles
div.layout-video {
@@ -20,9 +20,7 @@ div.layout-video {
line-height: 1.5;
margin: 1.25em 1em 0.5em 1em;
@include colors() {
color: c(medium-light);
}
@include themes.themed(color, "medium-light");
a {
font-weight: bold;
@@ -37,7 +35,7 @@ div.layout-video {
}
// Responsive
@mixin responsive--videos() {
@mixin responsive() {
div.layout-video {
padding: 1em 0;
+8 -2
View File
@@ -3,7 +3,11 @@
[
"@babel/preset-env",
{
"include": ["transform-arrow-functions", "transform-block-scoping", "transform-template-literals"],
"include": [
"transform-arrow-functions",
"transform-block-scoping",
"transform-template-literals"
],
"useBuiltIns": "entry",
"corejs": 3
}
@@ -11,7 +15,9 @@
[
"minify",
{
"removeConsole": true
"removeConsole": true,
// https://github.com/babel/minify/issues/904#issuecomment-424367995
"builtIns": false
}
]
]
+4 -15
View File
@@ -1,4 +1,4 @@
baseURL = "https://jarv.is/"
baseURL = "/"
languageCode = "en-us"
title = "Jake Jarvis"
@@ -26,8 +26,9 @@ disableAliases = true
[params]
description = "Hi there! I'm a frontend web developer based in Boston, Massachusetts specializing in the JAMstack, modern JavaScript frameworks, and progressive web apps."
image = "img/logo.png" # relative to assetDir root
image = "images/logo.png" # relative to assetDir root
mainSection = "notes" # content that appears in feeds
baseURL = "https://jarv.is" # different from baseURL above, this is only used where necessary
[params.theme]
maxWidth = 865 # px
defaultTheme = "light" # light or dark?
@@ -42,7 +43,7 @@ disableAliases = true
[author]
name = "Jake Jarvis"
image = "img/me.jpg" # relative to assetDir root
image = "images/me.jpg" # relative to assetDir root
email = "jake@jarv.is"
[author.social]
github = "jakejarvis"
@@ -56,18 +57,6 @@ disableAliases = true
instagram = "jakejarvis"
mastodon = "mastodon.social/@jakejarvis"
[module]
# we're grabbing Twemoji SVGs from an NPM helper package:
# https://www.npmjs.com/package/twemoji-emojis
[[module.mounts]]
source = "node_modules/twemoji-emojis/vendor/svg"
target = "static/vendor/emoji/svg"
# this is required, or else the Twemoji mount completely takes over /static:
# https://discourse.gohugo.io/t/can-hugo-copy-files-from-one-dir-to-another/24085/4
[[module.mounts]]
source = "static"
target = "static"
[frontmatter]
lastmod = ["date", "publishDate", ":default"]
+4 -18
View File
@@ -5,25 +5,9 @@ description: "An incredibly embarrassing and somewhat painful walkthrough of thi
image: "images/2001_12.png"
layout: etc
css: |
/*!
* Comic Neue typeface v2.5 - http://comicneue.com/
*
* Copyright (c) 2014 The Comic Neue Project Authors.
* Licensed under the SIL Open Font License, Version 1.1:
* https://github.com/crozynski/comicneue/blob/v2.5/OFL.txt
*/
@font-face {
font-family: "Comic Neue";
font-style: normal;
font-weight: 700;
font-display: swap;
src: url("{{ absURL "/vendor/fonts/comic-neue-bold-subset.woff2" | safeCSS }}") format("woff2"),
url("{{ absURL "/vendor/fonts/comic-neue-bold-subset.woff" | safeCSS }}") format("woff");
unicode-range: U+0000-00FF,U+2000-206F,U+20A0-20CF,U+2190-21FF,U+2200-22FF,U+2122;
}
body {
font-family: "Comic Neue", "Comic Sans MS", "Comic Sans", "Inter", sans-serif;
font-weight: 700;
font-weight: 700 !important;
}
div#content {
text-align: center;
@@ -40,17 +24,19 @@ css: |
border: 2px solid #e3d18c;
}
div#content code {
font-weight: 400;
font-weight: 400 !important;
}
div#content span.limegreen {
color: #32cd32;
}
header nav a#logo span#name {
font-size: 1.5em;
font-weight: 700 !important;
}
header nav ul li a span.text {
font-size: 1.05em;
line-height: 1.05;
font-weight: 700 !important;
}
footer div#copyright, footer div#poweredby {
font-size: 1.1em;
+92
View File
@@ -0,0 +1,92 @@
const gulp = require("gulp");
const execa = require("gulp-execa").task;
const htmlmin = require("gulp-html-minifier-terser");
const imagemin = require("gulp-imagemin");
const del = require("del");
// use up-to-date imagemin plugins instead of those bundled with gulp-imagemin:
const imageminMozjpeg = require("imagemin-mozjpeg");
const imageminPngquant = require("imagemin-pngquant");
const imageminGifsicle = require("imagemin-gifsicle");
const imageminSvgo = require("imagemin-svgo");
exports.default = gulp.series(
clean,
npx("webpack", ["--mode", "production", "--profile"]),
npx("hugo"),
gulp.parallel(
optimizeHtml,
optimizeImages,
),
);
exports.serve = gulp.parallel(
npx("webpack", ["serve"]),
npx("hugo", ["--watch", "--buildDrafts", "--buildFuture", "--verbose"]),
);
exports.clean = gulp.task(clean);
function optimizeHtml() {
return gulp
.src("public/**/*.html", { base: "./" })
.pipe(
htmlmin(
{
html5: true,
preserveLineBreaks: true,
collapseWhitespace: true,
collapseBooleanAttributes: true,
removeComments: true,
minifyCSS: false,
minifyJS: false,
}
)
)
.pipe(gulp.dest(".", { overwrite: true }));
}
function optimizeImages() {
return gulp
.src(["public/**/*.{gif,jpg,png,svg}", "!public/assets/emoji/*"], { base: "./" })
.pipe(
imagemin([
imageminMozjpeg({
quality: 85,
progressive: true,
}),
imageminPngquant({
quality: [0.7, 0.9],
speed: 1,
strip: true,
}),
imageminGifsicle(),
imageminSvgo(),
],
{
verbose: true,
})
)
.pipe(gulp.dest(".", { overwrite: true }));
}
function clean() {
return del([
"public/",
"builds/",
"_vendor/",
"static/assets/",
"data/manifest.json",
]);
}
// run a locally installed (i.e. ./node_modules/.bin/foo) binary, similar to a package.json script
function npx(bin, options) {
// WARNING: MAJOR HACKS AHEAD:
const cmd = `${bin} ${options ? options.join(" ") : ""}`.trim();
return execa(cmd, {
preferLocal: true,
shell: true,
stdio: "inherit",
});
}
+1 -1
View File
@@ -1,6 +1,6 @@
<!doctype html>
{{ printf "<!-- htmlmin:ignore -->" | safeHTML -}}
{{ printf "<!--\n ,,, ,,,\n ;\" ^; ;\" \",\n ; s$$$$$s ;\n , ss$$$$$$$ss ,\"\n ;$$$$$$$$$$$$$$$$\n $$$$$$$$$$$$$$$$$$ Hello, human. :)\n $$$$$\"\"\"$$$\"\"\"$$$$$$\n $$$$$ p\"$$$\"q $$$$$ %s\n $$$$ .$$$$$. $$$$\n $$$$$$$$$$$$$$$$$\n \"$$$$\"*\"$$$$\"\n \"$$.$$\"\n-->" ("humans.txt" | absURL) | safeHTML }}
{{ printf "<!--\n ,,, ,,,\n ;\" ^; ;\" \",\n ; s$$$$$s ;\n , ss$$$$$$$ss ,\"\n ;$$$$$$$$$$$$$$$$\n $$$$$$$$$$$$$$$$$$ Hello, human. :)\n $$$$$\"\"\"$$$\"\"\"$$$$$$\n $$$$$ p\"$$$\"q $$$$$ %s\n $$$$ .$$$$$. $$$$\n $$$$$$$$$$$$$$$$$\n \"$$$$\"*\"$$$$\"\n \"$$.$$\"\n-->" (print .Site.Params.baseURL "/humans.txt") | safeHTML }}
{{- printf "<!-- htmlmin:ignore -->" | safeHTML }}
<html lang="{{ .Site.LanguageCode | default "en" }}">
<head>
+7 -7
View File
@@ -2,24 +2,24 @@
{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\"?>" | safeHTML }}
<feed xmlns="http://www.w3.org/2005/Atom">
<title>{{ .Site.Title }}</title>
<id>{{ .Permalink }}</id>
<id>{{ print .Site.Params.baseUrl .Permalink }}</id>
<author>
<name>{{ .Site.Title }}</name>
<uri>{{ .Permalink }}</uri>
<uri>{{ print .Site.Params.baseUrl .Permalink }}</uri>
</author>
<generator>Hugo -- gohugo.io</generator>
{{- with .Site.Copyright }}
<rights>{{ . }}</rights>
{{- end }}
{{- with .Scratch.Get "authorImage" }}
<logo>{{ .Permalink }}</logo>
<logo>{{ print $.Site.Params.baseUrl .Permalink }}</logo>
{{- end }}
<updated>{{ .Site.LastChange.Format "2006-01-02T15:04:05Z" | safeHTML }}</updated>
{{- with .OutputFormats.Get "ATOM" }}
{{ printf `<link rel="self" type="%s" href="%s" />` .MediaType.Type .Permalink | safeHTML }}
{{ printf `<link rel="self" type="%s" href="%s" />` .MediaType.Type (print $.Site.Params.baseUrl .Permalink) | safeHTML }}
{{- end }}
{{- range .AlternativeOutputFormats }}
{{ printf `<link rel="alternate" type="%s" href="%s" />` .MediaType.Type .Permalink | safeHTML }}
{{ printf `<link rel="alternate" type="%s" href="%s" />` .MediaType.Type (print $.Site.Params.baseUrl .Permalink) | safeHTML }}
{{- end }}
{{- range (where .Site.RegularPages "Section" .Site.Params.mainSection) }}
<entry>
@@ -27,10 +27,10 @@
{{- with .Site.Author.name }}
<author>
<name>{{ . }}</name>
<uri>{{ $.Permalink }}</uri>
<uri>{{ print $.Site.Params.baseUrl $.Permalink }}</uri>
</author>
{{- end }}
<id>{{ .Permalink }}</id>
<id>{{ print $.Site.Params.baseUrl .Permalink }}</id>
<published>{{ .Date.UTC.Format "2006-01-02T15:04:05Z" | safeHTML }}</published>
<updated>{{ .Date.UTC.Format "2006-01-02T15:04:05Z" | safeHTML }}</updated>
<content type="html">
+14 -14
View File
@@ -1,33 +1,33 @@
{
"name": "{{ .Site.Title }}",
"short_name": "{{ (urls.Parse .Site.BaseURL).Host }}",
"short_name": "{{ (urls.Parse .Site.Params.baseURL).Host }}",
"icons": [
{
"src": "{{ (resources.Get "img/android-chrome-512x512.png").Permalink | safeJS }}",
{{ with index .Site.Data.manifest "images/android-chrome-512x512.png" }}{
"src": "{{ .src | absURL | safeJS }}",
"sizes": "512x512",
"type": "image/png",
"purpose": "any"
},
{
"src": "{{ (resources.Get "img/android-chrome-192x192.png").Permalink | safeJS }}",
},{{ end }}
{{ with index .Site.Data.manifest "images/android-chrome-192x192.png" }}{
"src": "{{ .src | absURL | safeJS }}",
"sizes": "192x192",
"type": "image/png",
"purpose": "any"
},
{
"src": "{{ (resources.Get "img/maskable-512x512.png").Permalink | safeJS }}",
},{{ end }}
{{ with index .Site.Data.manifest "images/maskable-512x512.png" }}{
"src": "{{ .src | absURL | safeJS }}",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "{{ (resources.Get "img/maskable-192x192.png").Permalink | safeJS }}",
},{{ end }}
{{ with index .Site.Data.manifest "images/maskable-192x192.png" }}{
"src": "{{ .src | absURL | safeJS }}",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
}
}{{ end }}
],
"start_url": "{{ .Site.BaseURL | safeJS }}",
"start_url": "/",
"display": "browser",
"background_color": "#ffffff",
"theme_color": "#0e6dc2"
+50 -17
View File
@@ -1,10 +1,54 @@
{{- partial "scripts/_bundle" . -}}
{{/* Pull in assets processed by Webpack */}}
{{- define "__head_css" -}}
{{ with .Site.Data.manifest }}
{{ with index . "main.css" }}
<link rel="stylesheet" href="{{ .src | absURL }}">
{{ end }}
{{ end }}
{{/* Page-specific styles set via front matter, piped through PostCSS and inlined */}}
{{- with .Params.css -}}
{{/* NOTE: This file doesn't end up getting published (which is good) */}}
{{- $target := path.Join $.File.Dir "css/inline.scss" -}}
{{- $css := . | resources.FromString $target | resources.PostCSS (dict "config" "postcss.config.js") -}}
<style>
{{ $css.Content | safeCSS }}
</style>
{{- end -}}
{{- end -}}
{{- define "__head_preload" -}}
{{ with .Site.Data.manifest }}
{{ with index . "fonts/inter-subset.var.woff2" }}
<link rel="preload" href="{{ .src | absURL }}" as="font" type="font/woff2" crossorigin>
{{ end }}
{{ with index . "fonts/roboto-mono-subset.var.woff2" }}
<link rel="preload" href="{{ .src | absURL }}" as="font" type="font/woff2" crossorigin>
{{ end }}
{{ with index . "main.js" }}
<link rel="preload" href="{{ .src | absURL }}" as="script">
{{ end }}
{{ end }}
{{- end -}}
{{- define "__body_js" -}}
<!-- inline the dark mode script to avoid a blinding flash of white background on loads -->
<script>(function(d){var u=d.document,f=u.body.classList,e=localStorage,c="dark_mode_pref",t=e.getItem(c),a="dark",n="light",r="{{ .Site.Params.Theme.defaultTheme | safeJS }}",o=u.querySelector(".dark-mode-toggle"),i=r===a,b=function(d){f.remove(a,n);f.add(d);i=d===a};t===a&&b(a);t===n&&b(n);if(!t){var s=function(d){return"(prefers-color-scheme: "+d+")"};d.matchMedia(s(a)).matches?b(a):d.matchMedia(s(n)).matches?b(n):b(r);d.matchMedia(s(a)).addListener((function(d){d.matches&&b(a)}));d.matchMedia(s(n)).addListener((function(d){d.matches&&b(n)}))}if(o){o.style.display="block";o.addEventListener("click",(function(){if(i){b(n);e.setItem(c,n)}else{b(a);e.setItem(c,a)}}),!0)}})(window)</script>
{{ with .Site.Data.manifest }}
{{ with index . "main.js" }}
<script async defer src="{{ .src | absURL }}" ></script>
{{ end }}
{{ end }}
{{- end -}}
{{/* Strip any markdown styling from page title for use in meta tags */}}
{{- with .Title -}}
{{- $.Scratch.Set "plainTitle" (. | markdownify | htmlUnescape | plainify) -}}
{{- end -}}
{{/* If this is a page/post, link View Source to specific file on GitHub; otherwise, just link to repo homepage */}}
{{- with .Site.Params.social.githubRepo }}
{{- $githubURL := print "https://github.com/" . }}
@@ -15,12 +59,11 @@
{{- end }}
{{- end }}
{{/* Chooses and initializes various images for use by JSON schema & open graph tags */}}
{{/* Author image (default) */}}
{{- with .Site.Author.image -}}
{{- with resources.Get . -}}
{{- $.Scratch.Set "authorImage" . -}}
{{- end -}}
{{- with index .Site.Data.manifest .Site.Author.image -}}
{{- $.Scratch.Set "authorImage" (dict "Permalink" (absURL .src) "Width" 1200 "Height" 1200 "MediaType" "image/jpeg") -}}
{{- end -}}
{{/* Page image (via frontmatter) */}}
{{- with .Params.image -}}
@@ -34,16 +77,6 @@
{{- end -}}
{{- end -}}
{{/* Site logo */}}
{{- with .Site.Params.image -}}
{{- with resources.Get . -}}
{{- $.Scratch.Set "logoImage" . -}}
{{- end -}}
{{- end -}}
{{/* Page-specific styles set via front matter, piped through PostCSS and inlined */}}
{{- with .Params.css -}}
{{/* NOTE: This file doesn't end up getting published (which is good) */}}
{{- $target := path.Join $.File.Dir "css/inline.scss" -}}
{{- $css := . | resources.FromString $target | resources.ExecuteAsTemplate $target . | resources.ToCSS (dict "targetPath" $target) | resources.PostCSS (dict "config" "postcss.config.js") -}}
{{- $.Scratch.Set "pageCss" $css.Content -}}
{{- with index .Site.Data.manifest .Site.Params.image -}}
{{- $.Scratch.Set "logoImage" (dict "Permalink" (absURL .src) "Width" 2048 "Height" 2048 "MediaType" "image/png") -}}
{{- end -}}
+1 -2
View File
@@ -4,8 +4,7 @@
{{ partialCached "head/mobile" . -}}
{{ partialCached "head/preload" . -}}
{{ partial "head/styles" . -}}
{{ partialCached "head/favicons" (dict "pngSizes" "192 48 32 16" "icoSizes" "16 32") -}}
{{ partialCached "head/favicons" (dict "pngSizes" "192 48 32 16" "icoSizes" "16 32" "manifest" .Site.Data.manifest) -}}
{{ partialCached "head/feeds" . -}}
{{ partial "head/canonical" . -}}
{{ partialCached "head/webmention" . -}}
{{ partial "head/schema" . -}}
+6 -2
View File
@@ -1,5 +1,9 @@
<link rel="canonical" href="{{ .Permalink }}">
<link rel="canonical" href="{{ print .Site.Params.baseURL .Permalink }}">
{{ if .Site.Params.social.webmentionIO }}
<link rel="webmention" href="{{ print $.Site.Params.baseURL "/api/mention/" }}">
<link rel="pingback" href="{{ print $.Site.Params.baseURL "/api/ping/" }}">
{{ end }}
<link rel="author" href="{{ "humans.txt" | absURL }}">
<link rel="pgpkey" href="{{ "pubkey.asc" | absURL }}" type="application/pgp-keys">
<link rel="license" href="{{ "license/" | absURL }}">
+6 -11
View File
@@ -1,17 +1,12 @@
{{- range (split .pngSizes " ") }}
{{- $faviconPng := resources.Get (printf "img/favicon-%v.png" .) }}
<!-- <link rel="icon" href="{{ $faviconPng.Permalink }}" sizes="{{ . }}x{{ . }}"> -->
{{- end -}}
{{- $s := slice -}}
{{- range (split .icoSizes " ") }}{{ $s = $s | append (printf "%vx%v" . .) }}{{ end -}}
{{- $faviconIco := resources.Get "img/favicon.ico" }}
<link rel="icon" href="{{ $faviconIco.Permalink }}"> <!-- sizes="{{ delimit $s " " }}" -->
{{- $faviconIco := index .manifest "images/favicon.ico" }}
<link rel="icon" href="{{ $faviconIco.src | absURL }}"> <!-- sizes="{{ delimit $s " " }}" -->
{{- $faviconSvg := resources.Get "img/favicon.svg" }}
<link rel="icon" href="{{ $faviconSvg.Permalink }}" type="image/svg+xml">
{{- $faviconSvg := index .manifest "images/favicon.svg" }}
<link rel="icon" href="{{ $faviconSvg.src | absURL }}" type="image/svg+xml">
{{- $appleIcon := resources.Get "img/apple-touch-icon.png" }}
<link rel="apple-touch-icon" href="{{ $appleIcon.Permalink }}" sizes="{{ $appleIcon.Width }}x{{ $appleIcon.Height }}">
{{- $appleIcon := index .manifest "images/apple-touch-icon.png" }}
<link rel="apple-touch-icon" href="{{ $appleIcon.src | absURL }}" sizes="180x180">
<link rel="manifest" href="{{ "site.webmanifest" | absURL }}">
+3 -3
View File
@@ -2,11 +2,11 @@
<meta property="og:site_name" content="{{ .Site.Title }}">
<meta property="og:type" content="{{ if and .IsPage (eq .Type .Site.Params.mainSection) }}article{{ else }}website{{ end }}">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="{{ .Permalink }}">
<meta property="og:url" content="{{ print .Site.Params.baseURL .Permalink }}">
<meta property="og:description" content="{{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }}">
{{- with .Scratch.Get "pageImage" }}
<meta property="og:image" content="{{ .Permalink }}">
<meta property="og:image" content="{{ print $.Site.Params.baseURL .Permalink }}">
<meta property="og:image:type" content="{{ .MediaType }}">
<meta property="og:image:width" content="{{ .Width }}">
<meta property="og:image:height" content="{{ .Height }}">
@@ -31,7 +31,7 @@
{{ with .Site.Params.social.facebookAppID }}<meta property="fb:app_id" content="{{ . }}">{{ end }}
<meta name="twitter:card" content="{{ if .IsPage }}summary_large_image{{ else }}summary{{ end }}">
<meta name="twitter:domain" content="{{ (urls.Parse .Site.BaseURL).Host }}">
<meta name="twitter:domain" content="{{ (urls.Parse .Site.Params.baseURL).Host }}">
{{- with .Site.Author.social.twitter }}
<meta name="twitter:site" content="{{ print "@" . }}">
<meta name="twitter:creator" content="{{ print "@" . }}">
+1 -4
View File
@@ -1,4 +1 @@
<link rel="preload" href="{{ "vendor/fonts/inter-subset.var.woff2" | absURL }}" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="{{ "vendor/fonts/roboto-mono-subset.var.woff2" | absURL }}" as="font" type="font/woff2" crossorigin>
{{ template "__preload_js" . }}
{{ template "__head_preload" . }}
+6 -6
View File
@@ -2,8 +2,8 @@
{
"@context": "http://schema.org",
"@type": "BlogPosting",
"url": {{ with .OutputFormats.Get "html" }}{{ .Permalink }}{{ end }},
"mainEntityOfPage": {{ with .OutputFormats.Get "html" }}{{ .Permalink }}{{ end }},
"url": {{ with .OutputFormats.Get "html" }}{{ print $.Site.Params.baseURL .Permalink }}{{ end }},
"mainEntityOfPage": {{ with .OutputFormats.Get "html" }}{{ print $.Site.Params.baseURL .Permalink }}{{ end }},
"name": {{ .Scratch.Get "plainTitle" }},
"headline": {{ .Scratch.Get "plainTitle" }},
"datePublished": {{ .PublishDate.Format "2006-01-02T15:04:05-07:00" }},
@@ -12,22 +12,22 @@
"description": {{ with .Description }}{{ . }}{{ else }}{{ .Site.Params.description }}{{ end }},
"wordCount": "{{ .WordCount }}",
"author": {
"@id": {{ print (absURL "/") "#author" }}
"@id": {{ print .Site.Params.baseURL $.Site.BaseURL "#author" }}
},
"publisher": {
"@type": "Organization",
"name": {{ .Site.Title }},
"url": {{ .Site.BaseURL }}{{ with .Scratch.Get "logoImage" }},
"url": {{ .Site.Params.baseURL }}{{ with .Scratch.Get "logoImage" }},
"logo": {
"@type": "ImageObject",
"url": {{ .Permalink }},
"url": {{ print $.Site.Params.baseURL .Permalink }},
"width": "{{ .Width }}",
"height": "{{ .Height }}"
}{{ end }}
}{{ with .Scratch.Get "pageImage" }},
"image": {
"@type": "ImageObject",
"url": {{ .Permalink }},
"url": {{ print $.Site.Params.baseURL .Permalink }},
"width": "{{ .Width }}",
"height": "{{ .Height }}"
}{{ end }}
+4 -4
View File
@@ -3,18 +3,18 @@
{
"@context": "http://schema.org",
"@type": "Person",
"@id": {{ print (absURL "/") "#author" }},
"@id": {{ print $.Site.Params.baseURL $.Site.BaseURL "#author" }},
"name": {{ .name }},
"url": {{ $.Site.BaseURL }},
"url": {{ print $.Site.Params.baseURL $.Site.BaseURL }},
"description": {{ $.Site.Params.description }},{{ with $.Scratch.Get "authorImage" }}
"image": {
"@type": "ImageObject",
"url": {{ .Permalink }},
"url": {{ print $.Site.Params.baseURL .Permalink }},
"width": "{{ .Width }}",
"height": "{{ .Height }}"
},{{ end }}
"sameAs": [
{{ $.Site.BaseURL }},{{ with .social }}
{{ print $.Site.Params.baseURL $.Site.BaseURL }},{{ with .social }}
{{ with .github }}{{ print "https://github.com/" . }},{{ end }}
{{ with .keybase }}{{ print "https://keybase.io/" . }},{{ end }}
{{ with .twitter }}{{ print "https://twitter.com/" . }},{{ end }}
+1 -11
View File
@@ -1,11 +1 @@
{{ $style := resources.Get "sass/main.scss" | resources.ExecuteAsTemplate "sass/main.scss" . | resources.ToCSS (dict "targetPath" "css/main.css") | resources.PostCSS (dict "config" "postcss.config.js") }}
<link rel="stylesheet" href="{{ $style.Permalink }}">
{{/* Page-specific styles set via front matter, piped through PostCSS and inlined (see functions/init) */}}
{{- with .Scratch.Get "pageCss" -}}
{{ printf "<!-- htmlmin:ignore -->" | safeHTML -}}
<style>
{{ . | safeCSS }}
</style>
{{- printf "<!-- htmlmin:ignore -->" | safeHTML }}
{{ end -}}
{{ template "__head_css" . }}
-4
View File
@@ -1,4 +0,0 @@
{{ if .Site.Params.social.webmentionIO }}
<link rel="webmention" href="{{ "api/mention/" | absURL }}">
<link rel="pingback" href="{{ "api/ping/" | absURL }}">
{{ end }}
+3 -3
View File
@@ -1,9 +1,9 @@
<header>
<nav>
<a class="no-underline" href="{{ .Site.BaseURL }}" id="logo" rel="me author" aria-label="{{ .Site.Title }}">
{{ $meImg := resources.Get .Site.Author.image }}
{{ $meImgSm := $meImg.Resize "160x160 q90 jpg" }}
<img id="selfie" src="{{ $meImgSm.Permalink }}" width="54" height="54" alt="Photo of Jake Jarvis">
{{ with index .Site.Data.manifest "images/tiny-selfie.jpg" }}
<img id="selfie" src="{{ .src | absURL }}" width="54" height="54" alt="Photo of Jake Jarvis">
{{ end }}
<span id="name">{{ .Site.Title }}</span>
</a>
-13
View File
@@ -1,13 +0,0 @@
{{ $js := resources.Get "js/index.js" | js.Build (dict "targetPath" "/js/app.js") | resources.Babel (dict "config" "babel.config.json" "noComments" true) }}
{{- .Scratch.Set "bundlePermalink" $js.Permalink -}}
{{- define "__preload_js" -}}
<link rel="preload" href="{{ $.Scratch.Get "bundlePermalink" }}" as="script">
{{- end -}}
{{- define "__body_js" -}}
<!-- inline the dark mode script to avoid a blinding flash of white background on loads -->
<script>(function(d){var u=d.document,f=u.body.classList,e=localStorage,c="dark_mode_pref",t=e.getItem(c),a="dark",n="light",r="{{ .Site.Params.Theme.defaultTheme | safeJS }}",o=u.querySelector(".dark-mode-toggle"),i=r===a,b=function(d){f.remove(a,n);f.add(d);i=d===a};t===a&&b(a);t===n&&b(n);if(!t){var s=function(d){return"(prefers-color-scheme: "+d+")"};d.matchMedia(s(a)).matches?b(a):d.matchMedia(s(n)).matches?b(n):b(r);d.matchMedia(s(a)).addListener((function(d){d.matches&&b(a)}));d.matchMedia(s(n)).addListener((function(d){d.matches&&b(n)}))}if(o){o.style.display="block";o.addEventListener("click",(function(){if(i){b(n);e.setItem(c,n)}else{b(a);e.setItem(c,a)}}),!0)}})(window)</script>
<script async defer src="{{ $.Scratch.Get "bundlePermalink" }}"></script>
{{- end -}}
+1 -1
View File
@@ -3,7 +3,7 @@ User-Agent: *
Disallow: /403.html
Disallow: /404.html
Disallow: /api/
Sitemap: {{ "sitemap.xml" | absURL }}
Sitemap: {{ print .Site.Params.baseUrl "/sitemap.xml" }}
{{- else }}
Disallow: /
{{- end }}
+6 -6
View File
@@ -2,7 +2,7 @@
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>{{ .Site.Title }}</title>
<link>{{ .Permalink }}</link>
<link>{{ print .Site.Params.baseUrl .Permalink }}</link>
<description>{{ with .Site.Params.description }}{{ . }}{{ else }}{{ .Title }}{{ end }}</description>
<generator>Hugo -- gohugo.io</generator>{{ with .Site.LanguageCode }}
<language>{{ . }}</language>{{ end }}{{ with .Site.Author.email }}
@@ -11,19 +11,19 @@
<copyright>{{ . }}</copyright>{{ end }}
<lastBuildDate>{{ .Site.LastChange.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</lastBuildDate>{{ with .Scratch.Get "authorImage" }}
<image>
<url>{{ .Permalink }}</url>
<url>{{ print $.Site.Params.baseUrl .Permalink }}</url>
<title>{{ $.Site.Title }}</title>
<link>{{ $.Permalink }}</link>
<link>{{ print $.Site.Params.baseUrl $.Permalink }}</link>
</image>{{ end }}{{ with .OutputFormats.Get "RSS" }}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" .Permalink .MediaType | safeHTML -}}
{{ printf "<atom:link href=%q rel=\"self\" type=%q />" (print $.Site.Params.baseUrl .Permalink) .MediaType | safeHTML -}}
{{ end }}
{{- range (where .Site.RegularPages "Section" .Site.Params.mainSection) }}
<item>
<title>{{ .Title | markdownify | htmlUnescape | plainify }}</title>
<link>{{ .Permalink }}</link>
<link>{{ print $.Site.Params.baseUrl .Permalink }}</link>
<pubDate>{{ .Date.Format "Mon, 02 Jan 2006 15:04:05 -0700" | safeHTML }}</pubDate>
{{ with .Site.Author.email }}<author>{{ . }}{{ with $.Site.Author.name }} ({{ . }}){{ end }}</author>{{ end }}
<guid>{{ .Permalink }}</guid>
<guid>{{ print $.Site.Params.baseUrl .Permalink }}</guid>
<description>
{{ .Content | html }}
</description>
+1 -1
View File
@@ -2,7 +2,7 @@
<p align="center">
{{ with .Get "link" }}<a href="{{ . }}">{{ end }}
<img src="{{ $optimized.Permalink }}" width="{{ $optimized.Width }}" height="{{ $optimized.Height }}"
<img src="{{ print .Site.Params.baseUrl $optimized.Permalink }}" width="{{ $optimized.Width }}" height="{{ $optimized.Height }}"
{{- with .Get "alt" }} alt="{{ . | safeHTML }}"{{ end }}
{{- with .Inner }} alt="{{ . | $.Page.RenderString | plainify | safeHTML }}"{{ end }}>
{{ if .Get "link" }}</a>{{ end }}
+1 -1
View File
@@ -1 +1 @@
<p>Your browser does not support HTML5 video. {{ with .Page.Resources.GetMatch (.Get "mp4") }}<a href="{{ .Permalink }}">Click to open the .mp4 video directly.</a>{{ end }}</p>
<p>Your browser does not support HTML5 video. {{ with .Page.Resources.GetMatch (.Get "mp4") }}<a href="{{ print $.Site.Params.baseUrl .Permalink }}">Click to open the .mp4 video directly.</a>{{ end }}</p>
+1 -1
View File
@@ -2,7 +2,7 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{{- range .Data.Pages }}
<url>
<loc>{{ .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
<loc>{{ print $.Site.Params.baseURL .Permalink }}</loc>{{ if not .Lastmod.IsZero }}
<lastmod>{{ safeHTML ( .Lastmod.Format "2006-01-02T15:04:05-07:00" ) }}</lastmod>{{ end }}{{ with .Sitemap.ChangeFreq }}
<changefreq>{{ . }}</changefreq>{{ end }}{{ if ge .Sitemap.Priority 0.0 }}
<priority>{{ .Sitemap.Priority }}</priority>{{ end }}
Regular → Executable
+35 -23
View File
@@ -13,13 +13,11 @@
"type": "git",
"url": "git+https://github.com/jakejarvis/jarv.is.git"
},
"main": "assets/js/index.js",
"scripts": {
"clean": "rimraf public/ resources/ builds/ _vendor/ .vercel/cache/ $TMPDIR/hugo_cache/ hugo_stats.json",
"start": "hugo server --buildDrafts --buildFuture --port=${PORT:-1337} --baseURL=/ --appendPort=false --bind=0.0.0.0 --verbose",
"build": "run-s build:** minify:**",
"build:hugo": "hugo --gc --cleanDestinationDir --verbose",
"minify:html": "html-minifier --html5 --collapse-whitespace --collapse-boolean-attributes --preserve-line-breaks --minify-css --remove-comments --file-ext html --input-dir public --output-dir public **/*.html",
"minify:img": "glob-exec --parallel --foreach 'public/**/{img,images}/' -- imagemin '{{file.path}}*' --plugin=mozjpeg --plugin.mozjpeg.progressive --plugin.mozjpeg.quality=85 --plugin=pngquant --plugin.pngquant.quality={0.1,0.3} --plugin.pngquant.speed=1 --plugin.pngquant.strip --plugin=gifsicle --plugin=svgo --out-dir='{{file.path}}'",
"build": "gulp",
"start": "gulp serve",
"clean": "gulp clean",
"lint": "run-s lint:**",
"lint:ts": "tsc --noEmit",
"lint:js": "eslint --ext .js,.ts .",
@@ -33,8 +31,8 @@
"@fontsource/comic-neue": "4.4.5",
"@fontsource/inter": "4.4.5",
"@fontsource/roboto-mono": "4.4.5",
"@sentry/node": "^6.6.0",
"@sentry/tracing": "^6.6.0",
"@sentry/node": "^6.7.1",
"@sentry/tracing": "^6.7.1",
"dotenv": "^10.0.0",
"faunadb": "fauna/faunadb-js#master",
"graphql": "^15.5.0",
@@ -53,7 +51,7 @@
},
"devDependencies": {
"@babel/cli": "^7.14.5",
"@babel/core": "^7.14.5",
"@babel/core": "^7.14.6",
"@babel/eslint-parser": "^7.14.5",
"@babel/preset-env": "^7.14.5",
"@babel/preset-typescript": "^7.14.5",
@@ -64,36 +62,46 @@
"@types/pluralize": "^0.0.29",
"@types/twemoji": "^12.1.1",
"@types/xml2js": "^0.4.8",
"@typescript-eslint/eslint-plugin": "^4.26.1",
"@typescript-eslint/parser": "^4.26.1",
"@vercel/node": "^1.11.0",
"@typescript-eslint/eslint-plugin": "^4.27.0",
"@typescript-eslint/parser": "^4.27.0",
"@vercel/node": "^1.11.1",
"autoprefixer": "^10.2.6",
"babel-loader": "^8.2.2",
"babel-minify": "^0.5.1",
"cross-env": "^7.0.3",
"eslint": "~7.28.0",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"copy-webpack-plugin": "^9.0.0",
"css-loader": "^5.2.6",
"del": "^6.0.0",
"eslint": "~7.29.0",
"eslint-config-prettier": "~8.3.0",
"eslint-plugin-compat": "~3.9.0",
"eslint-plugin-import": "~2.23.4",
"eslint-plugin-prettier": "~3.4.0",
"glob-exec": "^0.1.1",
"html-minifier": "^4.0.0",
"hugo-extended": "jakejarvis/hugo-extended#9f615221831632cb3b8879ab3fc420fff921e1fd",
"imagemin-cli": "^6.0.0",
"file-loader": "^6.2.0",
"gulp": "^4.0.2",
"gulp-cli": "^2.3.0",
"gulp-execa": "^2.0.0",
"gulp-html-minifier-terser": "^6.0.1",
"gulp-imagemin": "^7.1.0",
"hugo-extended": "jakejarvis/hugo-extended#7bd97c7bed83327cc2a6c8426bced5532eea160e",
"lint-staged": "^11.0.0",
"markdownlint-cli": "~0.27.1",
"mini-css-extract-plugin": "^1.6.0",
"npm-run-all": "^4.1.5",
"postcss": "^8.3.2",
"postcss": "^8.3.5",
"postcss-clean": "jakejarvis/postcss-clean#master",
"postcss-cli": "^8.3.1",
"postcss-color-rgba-fallback": "^4.0.0",
"postcss-combine-duplicated-selectors": "^10.0.3",
"postcss-focus": "^5.0.1",
"postcss-import": "^14.0.2",
"postcss-merge-rules": "^5.0.2",
"postcss-loader": "^6.1.0",
"postcss-normalize-charset": "^5.0.1",
"postcss-reporter": "^7.0.2",
"postcss-svgo": "^5.0.2",
"prettier": "^2.3.1",
"rimraf": "^3.0.2",
"sass": "^1.35.1",
"sass-loader": "^12.1.0",
"simple-git-hooks": "^2.4.1",
"stylelint": "~13.13.1",
"stylelint-config-prettier": "~8.0.2",
@@ -101,8 +109,12 @@
"stylelint-no-unsupported-browser-features": "~5.0.1",
"stylelint-prettier": "~1.2.0",
"stylelint-scss": "~3.19.0",
"typescript": "^4.3.2",
"web-vitals": "^2.0.1"
"typescript": "^4.3.4",
"webpack": "^5.39.1",
"webpack-assets-manifest": "^5.0.6",
"webpack-cli": "^4.7.2",
"webpack-dev-server": "^3.11.2",
"webpack-subresource-integrity": "^1.5.2"
},
"optionalDependencies": {
"imagemin-gifsicle": "^7.0.0",
+1 -1
View File
@@ -14,7 +14,7 @@ module.exports = {
"background-image"
],
}),
require("postcss-merge-rules")(),
require("postcss-combine-duplicated-selectors")(),
require("postcss-normalize-charset")(),
require("postcss-clean")({
compatibility: "*",
Loaded 100 of 105 files, more files were not shown because too many files have changed in this diff. Show more