Update CSS Pipeline (#4)
All checks were successful
Build and Deploy / build_and_deploy (push) Successful in 1m19s
All checks were successful
Build and Deploy / build_and_deploy (push) Successful in 1m19s
The goal of this change was to speed up my CSS pipeline. Previously builds would take up to 30s because it had to rebuild the CSS for every page (I inlined the CSS). This updates the pipeline to remain somewhat the same, but offloads the busywork of computing my theme CSS (my design system in other words), and is replaced by a mostly static file (`css/global/lilypad.css`), which I can update as my design system changes. I also offloaded several of my utility classes as I know I will want to use them in other sites I design, so it made sense to move them as well. The new pipeline makes use of 11ty's bundle feature (newly included in 11ty v3), which allows me to bundle all my CSS together into one file. Since I know my core styles like `lilypad.css` will always remain the same, I decided to keep that inline. I use the `transforms` feature for bundling to run a PostCSS transform on the bundled output, which resolves any imports and minifies the final output. In order to cut down my build times even further, I removed my XML minifier - it was taking upwards of 3 seconds to minify XML to probably a small benefit to end users. Reviewed-on: #4 Co-authored-by: Devin Haska <wonderfulfrog@noreply.git.cloud.haska.me> Co-committed-by: Devin Haska <wonderfulfrog@noreply.git.cloud.haska.me>
This commit is contained in:
parent
07a71e8f99
commit
efcdb7296e
59 changed files with 344 additions and 1996 deletions
13
config/bundles/css.js
Normal file
13
config/bundles/css.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import postcss from "postcss";
|
||||
import postcssImport from "postcss-import";
|
||||
|
||||
export default {
|
||||
transforms: [
|
||||
async function (content) {
|
||||
const css = await postcss([postcssImport])
|
||||
.process(content, { from: "src/includes/css/styles.css" })
|
||||
.then((result) => result.css);
|
||||
return css;
|
||||
},
|
||||
],
|
||||
};
|
5
config/bundles/index.js
Normal file
5
config/bundles/index.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
import css from "./css.js";
|
||||
|
||||
export default {
|
||||
css,
|
||||
};
|
|
@ -1 +0,0 @@
|
|||
export const ASSETS_FONTS_PATH = "/assets/fonts";
|
|
@ -1,22 +0,0 @@
|
|||
export default {
|
||||
light: {
|
||||
primary: "oklch(0.6 0.1025 212.16)",
|
||||
secondary: "oklch(0.61 0.2232 31.48)",
|
||||
background: "oklch(0.98 0 0)",
|
||||
surface: "oklch(0.96 0.0078 207.9)",
|
||||
border: "oklch(0.87 0.045077 207.8465)",
|
||||
text: "oklch(0.15 0 0)",
|
||||
fadeText: "oklch(0.45 0.0214 207.84)",
|
||||
shadow: "oklch(0.39 0.0688 212.35)",
|
||||
},
|
||||
dark: {
|
||||
primary: "oklch(0.57 0.0991 213.4)",
|
||||
secondary: "oklch(0.55 0.1982 31.52)",
|
||||
background: "oklch(0.2 0 0)",
|
||||
surface: "oklch(0.26 0.0106 233.21)",
|
||||
border: "oklch(0.27 0.0238 245.26)",
|
||||
text: "oklch(0.98 0 0)",
|
||||
fadeText: "oklch(0.78 0.018 207.85)",
|
||||
shadow: "oklch(0.39 0.0688 212.35)",
|
||||
},
|
||||
};
|
|
@ -1,38 +0,0 @@
|
|||
export default {
|
||||
display: {
|
||||
family: "Atikinson Hyperlegible Next",
|
||||
format: "woff2",
|
||||
styles: {
|
||||
Regular: {
|
||||
path: "/hyperlegible/AtkinsonHyperlegibleNextVF-Variable.woff2",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "125 950",
|
||||
fontStretch: "75% 125%",
|
||||
},
|
||||
},
|
||||
},
|
||||
body: {
|
||||
family: "Atikinson Hyperlegible Next",
|
||||
format: "woff2",
|
||||
styles: {
|
||||
Regular: {
|
||||
path: "/hyperlegible/AtkinsonHyperlegibleNextVF-Variable.woff2",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "125 950",
|
||||
fontStretch: "75% 125%",
|
||||
},
|
||||
},
|
||||
},
|
||||
monospace: {
|
||||
family: "Atikinson Hyperlegible Mono",
|
||||
format: "woff2",
|
||||
styles: {
|
||||
Regular: {
|
||||
path: "/hyperlegible-mono/AtkinsonHyperlegibleMonoVF-Variable.woff2",
|
||||
fontStyle: "normal",
|
||||
fontWeight: "125 950",
|
||||
fontStretch: "75% 125%",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
|
@ -1,11 +0,0 @@
|
|||
export default {
|
||||
0: 0,
|
||||
0.25: 4,
|
||||
0.5: 8,
|
||||
1: 16,
|
||||
1.5: 24,
|
||||
2: 32,
|
||||
3: 48,
|
||||
4: 64,
|
||||
5: 80,
|
||||
};
|
|
@ -1,29 +1,15 @@
|
|||
import { JSDOM } from "jsdom";
|
||||
|
||||
// From coryd.dev
|
||||
// https://www.coryd.dev/posts/2025/generating-absolute-urls-in-my-rss-feeds/
|
||||
const convertRelativeLinks = (htmlContent, url) => {
|
||||
if (!htmlContent || !url) return htmlContent;
|
||||
|
||||
const dom = new JSDOM(htmlContent);
|
||||
const document = dom.window.document;
|
||||
const baseUrl = url.replace(/\/$/, "");
|
||||
|
||||
document.querySelectorAll("a[href]").forEach((link) => {
|
||||
let href = link.getAttribute("href");
|
||||
|
||||
if (href.startsWith("#")) {
|
||||
link.remove();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!href.startsWith("http://") && !href.startsWith("https://"))
|
||||
link.setAttribute(
|
||||
"href",
|
||||
`${url.replace(/\/$/, "")}/${href.replace(/^\/+/, "")}`,
|
||||
return htmlContent.replace(
|
||||
/(href|src)=(['"])(?![a-z][a-z0-9+.-]*:|\/\/)([^'"]+)\2/gi,
|
||||
(_, attr, quote, relUrl) => {
|
||||
const clean = relUrl.replace(/^\//, "");
|
||||
return `${attr}=${quote}${baseUrl}/${clean}${quote}`;
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
return document.body.innerHTML;
|
||||
};
|
||||
|
||||
export default {
|
||||
|
|
|
@ -2,7 +2,6 @@ import collection from "./collection.js";
|
|||
import date from "./date.js";
|
||||
import feed from "./feed.js";
|
||||
import general from "./general.js";
|
||||
import postcss from "./postcss/index.js";
|
||||
import tag from "./tag.js";
|
||||
|
||||
export default {
|
||||
|
@ -10,6 +9,5 @@ export default {
|
|||
...date,
|
||||
...feed,
|
||||
...general,
|
||||
...postcss,
|
||||
...tag,
|
||||
};
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import postcss from "./postcss.js";
|
||||
|
||||
export default {
|
||||
...postcss,
|
||||
};
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Implementation sourced from eleventyone starter kit
|
||||
* https://github.com/philhawksworth/eleventyone
|
||||
* ---
|
||||
* https://github.com/philhawksworth/eleventyone/blob/master/src/site/css/styles.11ty.js
|
||||
*/
|
||||
import { default as postcssBase } from "postcss";
|
||||
import postcssImport from "postcss-import";
|
||||
import postcssImportExtGlob from "postcss-import-ext-glob";
|
||||
import autoprefixer from "autoprefixer";
|
||||
import cssnano from "cssnano";
|
||||
|
||||
import colors from "./utils/colors.js";
|
||||
import fontFamily from "./utils/font-family.js";
|
||||
import fontVariables from "./utils/font-variables.js";
|
||||
import spacing from "./utils/spacing.js";
|
||||
|
||||
const postcss = async (rawCss) => {
|
||||
const css = `${rawCss}${fontFamily}${fontVariables}${colors}${spacing}`;
|
||||
return await postcssBase([
|
||||
postcssImportExtGlob,
|
||||
postcssImport,
|
||||
autoprefixer,
|
||||
cssnano,
|
||||
])
|
||||
.process(css, { from: "src/includes/css/styles.css" })
|
||||
.then((result) => result.css);
|
||||
};
|
||||
|
||||
export default {
|
||||
postcss,
|
||||
};
|
|
@ -1,34 +0,0 @@
|
|||
import colorSchemes from "../../../design-tokens/colors.js";
|
||||
import { helperClassesToCss } from "./helper-classes.js";
|
||||
|
||||
const lightScheme = colorSchemes.light;
|
||||
const darkScheme = colorSchemes.dark;
|
||||
|
||||
const colorToCss = (key, value) => `--color-${key}: ${value};`;
|
||||
|
||||
const colorSchemeToCss = (scheme) =>
|
||||
Object.entries(scheme).reduce(
|
||||
(css, [key, value]) => css + colorToCss(key, value),
|
||||
``,
|
||||
);
|
||||
|
||||
const lightCss = colorSchemeToCss(lightScheme);
|
||||
const darkCss = colorSchemeToCss(darkScheme);
|
||||
|
||||
const colorSchemeToHelperClassesCss = (scheme, helperClasses) => {
|
||||
return Object.entries(scheme).reduce((css, [key]) => {
|
||||
return css + helperClassesToCss(helperClasses, key, `var(--color-${key})`);
|
||||
}, ``);
|
||||
};
|
||||
|
||||
const helperClasses = [
|
||||
["text", ["color"]],
|
||||
["bg", ["background-color"]],
|
||||
];
|
||||
|
||||
const helperClassesCss = colorSchemeToHelperClassesCss(
|
||||
lightScheme,
|
||||
helperClasses,
|
||||
);
|
||||
|
||||
export default `:root{${lightCss}}${helperClassesCss}@media (prefers-color-scheme: dark) {:root{${darkCss}}}`;
|
|
@ -1,58 +0,0 @@
|
|||
import path from "path";
|
||||
|
||||
import fonts from "../../../design-tokens/fonts.js";
|
||||
|
||||
const getFontUrl = (src) => path.join("/assets/fonts", src);
|
||||
|
||||
const fontsToCss = (fonts) => {
|
||||
return Object.entries(fonts).reduce((css, [, fontProperties]) => {
|
||||
const family = fontProperties.family;
|
||||
const format = fontProperties.format;
|
||||
const styles = fontProperties.styles;
|
||||
|
||||
return (
|
||||
css +
|
||||
Object.entries(styles).reduce((css, [variant, fontFamily]) => {
|
||||
const url = getFontUrl(fontFamily.path);
|
||||
const style = fontFamily.fontStyle;
|
||||
const weight = fontFamily.fontWeight;
|
||||
const stretch = fontFamily.fontStretch;
|
||||
const postScriptName = [family, variant].join("-").replaceAll(" ", "");
|
||||
|
||||
return (
|
||||
css +
|
||||
fontFamilyToCss(
|
||||
family,
|
||||
style,
|
||||
weight,
|
||||
stretch,
|
||||
url,
|
||||
family,
|
||||
postScriptName,
|
||||
format,
|
||||
)
|
||||
);
|
||||
}, ``)
|
||||
);
|
||||
}, ``);
|
||||
};
|
||||
|
||||
const fontFamilyToCss = (
|
||||
family,
|
||||
style,
|
||||
weight,
|
||||
stretch,
|
||||
url,
|
||||
localName,
|
||||
postScriptName,
|
||||
format,
|
||||
) => `@font-face {
|
||||
font-family: ${family};
|
||||
font-style: ${style};
|
||||
font-weight: ${weight};
|
||||
font-stretch: ${stretch};
|
||||
font-display: swap;
|
||||
src: local("${localName}"), local("${postScriptName}"), url("${url}") format("${format}")
|
||||
}\n`;
|
||||
|
||||
export default fontsToCss(fonts);
|
|
@ -1,57 +0,0 @@
|
|||
/*
|
||||
* Fallbacks from Modern Font Stacks.
|
||||
* https://modernfontstacks.com/
|
||||
*/
|
||||
|
||||
import fonts from "../../../design-tokens/fonts.js";
|
||||
|
||||
const displayFallbacks = [
|
||||
"ui-monospace",
|
||||
"Cascadia Code",
|
||||
"Source Code Pro",
|
||||
"Menlo",
|
||||
"Consolas",
|
||||
"DejaVu Sans Mono",
|
||||
"monospace",
|
||||
];
|
||||
|
||||
const bodyFallbacks = [
|
||||
"ui-monospace",
|
||||
"Cascadia Code",
|
||||
"Source Code Pro",
|
||||
"Menlo",
|
||||
"Consolas",
|
||||
"DejaVu Sans Mono",
|
||||
"monospace",
|
||||
];
|
||||
|
||||
const monoFallbacks = [
|
||||
"ui-monospace",
|
||||
"Cascadia Code",
|
||||
"Source Code Pro",
|
||||
"Menlo",
|
||||
"Consolas",
|
||||
"DejaVu Sans Mono",
|
||||
"monospace",
|
||||
];
|
||||
|
||||
const fallbacks = {
|
||||
display: displayFallbacks,
|
||||
body: bodyFallbacks,
|
||||
monospace: monoFallbacks,
|
||||
};
|
||||
|
||||
const fontsToCss = (fonts) => {
|
||||
return Object.entries(fonts).reduce((css, [fontType, fontProperties]) => {
|
||||
const family = fontProperties.family;
|
||||
|
||||
const fontTypeCss = fontFamilyToCss(fontType, family);
|
||||
|
||||
return css + fontTypeCss;
|
||||
}, ``);
|
||||
};
|
||||
|
||||
const fontFamilyToCss = (type, value) =>
|
||||
`--font-family-${type}: ${value},${fallbacks[type].join(",")};`;
|
||||
|
||||
export default `:root{${fontsToCss(fonts)}}`;
|
|
@ -1,43 +0,0 @@
|
|||
/**
|
||||
* Given an array of CSS properties, output css properties
|
||||
* with each property equal to `value`
|
||||
*/
|
||||
export const cssPropertiesToCss = (cssProperties, value) => {
|
||||
return cssProperties.reduce((css, cssProp) => {
|
||||
return css + `${cssProp}:${value};`;
|
||||
}, ``);
|
||||
};
|
||||
|
||||
/**
|
||||
* Given a helperClass (string) and array of cssProperties,
|
||||
* will generate a css class named helperClass that has
|
||||
* all cssProperties mapped to value.
|
||||
*/
|
||||
export const helperClassToCss = (helperClass, cssProperties, value) => {
|
||||
const cssProps = cssPropertiesToCss(cssProperties, value);
|
||||
return `.${helperClass}{${cssProps}}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Given an array of helperClasses that map to cssProperties,
|
||||
* output a string of CSS that maps the helperClass (with variant modifier)
|
||||
* to the array of css properties with each css property equal to
|
||||
* value
|
||||
*
|
||||
* e.g.
|
||||
* helperClasses = [["text", ["color"]]],
|
||||
* variant = "primary",
|
||||
* value = "#000"
|
||||
*
|
||||
* Will output the following:
|
||||
* .text-primary {
|
||||
* color: #000;
|
||||
* }
|
||||
*/
|
||||
export const helperClassesToCss = (helperClasses, variant, value) => {
|
||||
return helperClasses.reduce((css, [helperClass, cssProperties]) => {
|
||||
return (
|
||||
css + helperClassToCss(`${helperClass}-${variant}`, cssProperties, value)
|
||||
);
|
||||
}, ``);
|
||||
};
|
|
@ -1,51 +0,0 @@
|
|||
import spacing from "../../../design-tokens/spacing.js";
|
||||
import { helperClassesToCss } from "./helper-classes.js";
|
||||
|
||||
const spacingToCss = (variant, value) =>
|
||||
`--spacing-${variant.replace(".", "\\.")}: ${value}px;`;
|
||||
|
||||
const spacingToHelperClassesCss = (spacingValues, helperClasses) => {
|
||||
return Object.entries(spacingValues).reduce((css, [spacingVariant]) => {
|
||||
const variant = spacingVariant.replace(".", "\\.");
|
||||
return (
|
||||
css +
|
||||
helperClassesToCss(helperClasses, variant, `var(--spacing-${variant})`)
|
||||
);
|
||||
}, ``);
|
||||
};
|
||||
|
||||
const helperClasses = [
|
||||
["m", ["margin"]],
|
||||
["my", ["margin-block-start", "margin-block-end"]],
|
||||
["mx", ["margin-inline-start", "margin-inline-end"]],
|
||||
["ml", ["margin-inline-start"]],
|
||||
["mr", ["margin-inline-start"]],
|
||||
["mt", ["margin-block-start"]],
|
||||
["mb", ["margin-block-end"]],
|
||||
["p", ["padding"]],
|
||||
["py", ["padding-block-start", "padding-block-end"]],
|
||||
["px", ["padding-inline-start", "padding-inline-end"]],
|
||||
["pl", ["padding-inline-start"]],
|
||||
["pr", ["padding-inline-start"]],
|
||||
["pt", ["padding-block-start"]],
|
||||
["pb", ["padding-block-end"]],
|
||||
["w", ["width"]],
|
||||
["h", ["height"]],
|
||||
["size", ["width", "height"]],
|
||||
["radius", ["border-radius"]],
|
||||
["gap", ["gap"]],
|
||||
["row-gap", ["row-gap"]],
|
||||
["column-gap", ["column-gap"]],
|
||||
["flow-space", ["--flow-space"]],
|
||||
];
|
||||
|
||||
const spacingVariablesCss = Object.entries(spacing).reduce(
|
||||
(css, [variant, value]) => css + spacingToCss(variant, value),
|
||||
``,
|
||||
);
|
||||
|
||||
const helperCss = spacingToHelperClassesCss(spacing, helperClasses);
|
||||
|
||||
const css = `:root{${spacingVariablesCss}}${helperCss}`;
|
||||
|
||||
export default css;
|
|
@ -1,4 +1,3 @@
|
|||
import htmlConfigTransform from "./html-config.js";
|
||||
import xmlConfigTransform from "./xml-config.js";
|
||||
|
||||
export default { htmlConfigTransform, xmlConfigTransform };
|
||||
export default { htmlConfigTransform };
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
import minifyXML from "minify-xml";
|
||||
|
||||
export default function (eleventyConfig) {
|
||||
eleventyConfig.addTransform("xml-minify", (content, path) => {
|
||||
if (path && path.endsWith(".xml")) {
|
||||
return minifyXML(content, {
|
||||
shortenNamespaces: false,
|
||||
});
|
||||
}
|
||||
return content;
|
||||
});
|
||||
}
|
|
@ -1,15 +1,13 @@
|
|||
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||
|
||||
import { collectionByTag } from "./config/collections/index.js";
|
||||
import bundles from "./config/bundles/index.js";
|
||||
import filters from "./config/filters/index.js";
|
||||
import markdown from "./config/plugins/markdown.js";
|
||||
import shortcodes from "./config/shortcodes/index.js";
|
||||
import transforms from "./config/transforms/index.js";
|
||||
|
||||
export default function (eleventyConfig) {
|
||||
// --------------------- Watch Targets -----------------------
|
||||
eleventyConfig.addWatchTarget("./src/includes/css");
|
||||
|
||||
// --------------------- Passthrough File Copy -----------------------
|
||||
["src/assets/fonts/", "src/assets/images"].forEach((path) =>
|
||||
eleventyConfig.addPassthroughCopy(path),
|
||||
|
@ -18,6 +16,11 @@ export default function (eleventyConfig) {
|
|||
// --------------------- Markdown -----------------------
|
||||
eleventyConfig.setLibrary("md", markdown);
|
||||
|
||||
// --------------------- Bundles -----------------------
|
||||
Object.keys(bundles).forEach((bundleName) => {
|
||||
eleventyConfig.addBundle(bundleName, bundles[bundleName]);
|
||||
});
|
||||
|
||||
// --------------------- Collections -----------------------
|
||||
eleventyConfig.addCollection("postsByTag", (collection) =>
|
||||
collectionByTag(collection, "post"),
|
||||
|
|
1185
package-lock.json
generated
1185
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -23,7 +23,6 @@
|
|||
"dayjs": "^1.11.10",
|
||||
"dotenv": "^16.4.5",
|
||||
"html-minifier-terser": "^7.2.0",
|
||||
"jsdom": "^26.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"markdown-it-abbr": "^2.0.0",
|
||||
"markdown-it-anchor": "^8.6.7",
|
||||
|
@ -31,11 +30,9 @@
|
|||
"markdown-it-footnote": "^4.0.0",
|
||||
"markdown-it-image-figures": "^2.1.1",
|
||||
"markdown-it-prism": "^2.3.0",
|
||||
"minify-xml": "^4.5.2",
|
||||
"pluralize": "^8.0.0",
|
||||
"postcss": "^8.5.3",
|
||||
"postcss-import": "^16.1.0",
|
||||
"postcss-import-ext-glob": "^2.1.1",
|
||||
"upload-to-bunny": "^1.4.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ module.exports = {
|
|||
linkTitle: "View book details",
|
||||
eleventyComputed: {
|
||||
tertiary: (data) =>
|
||||
`<p class="[ flow-space-0.5 ]"><span class="[ text-fadeText ]">by</span> ${data.author}</p>`,
|
||||
`<p class="[ flow-space-2 ]"><span class="[ text-fadeText ]">by</span> ${data.author}</p>`,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
@ -476,7 +476,7 @@ box-shadow:
|
|||
1px 1px 0px var(--color-shadow),
|
||||
2px 2px 0 var(--color-shadow);
|
||||
|
||||
border-radius: var(--spacing-0\.25);
|
||||
border-radius: var(--spacing-1);
|
||||
border: 1px solid var(--color-shadow);
|
||||
|
||||
transition:
|
||||
|
|
|
@ -1,24 +1,12 @@
|
|||
import path from "path";
|
||||
|
||||
import { ASSETS_FONTS_PATH } from "../../config/constants/paths.js";
|
||||
import fonts from "../../config/design-tokens/fonts.js";
|
||||
|
||||
const getFontUrl = (src) => path.join(ASSETS_FONTS_PATH, src);
|
||||
|
||||
const preloads = [
|
||||
{
|
||||
as: "font",
|
||||
href: getFontUrl(fonts.display.styles.Regular.path),
|
||||
href: "/assets/fonts/hyperlegible/AtkinsonHyperlegibleNextVF-Variable.woff2",
|
||||
crossorigin: true,
|
||||
},
|
||||
{
|
||||
as: "font",
|
||||
href: getFontUrl(fonts.body.styles.Regular.path),
|
||||
crossorigin: true,
|
||||
},
|
||||
{
|
||||
as: "font",
|
||||
href: getFontUrl(fonts.monospace.styles.Regular.path),
|
||||
href: "/assets/fonts/hyperlegible-mono/AtkinsonHyperlegibleMonoVF-Variable.woff2",
|
||||
crossorigin: true,
|
||||
},
|
||||
];
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
align-items: center;
|
||||
color: var(--color-text);
|
||||
display: inline-flex;
|
||||
gap: var(--spacing-0\.5);
|
||||
padding: var(--spacing-0\.5) var(--spacing-1);
|
||||
gap: var(--spacing-2);
|
||||
padding: var(--spacing-2) var(--spacing-4);
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
transition: transform 0.3s var(--transition-bounce);
|
||||
|
@ -11,7 +11,7 @@
|
|||
|
||||
&::before,
|
||||
&::after {
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
content: "";
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.card {
|
||||
border: 1px solid var(--color-shadow);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
padding: var(--spacing-1);
|
||||
border-radius: var(--spacing-2);
|
||||
padding: var(--spacing-4);
|
||||
background-color: var(--color-surface);
|
||||
}
|
||||
|
||||
.card--secondary {
|
||||
|
|
|
@ -1,38 +1,30 @@
|
|||
.media-metadata-grid {
|
||||
display: grid;
|
||||
gap: var(--spacing-4);
|
||||
|
||||
@container (min-width: 48rem) {
|
||||
grid-template-columns: 200px 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.media-metadata {
|
||||
display: grid;
|
||||
grid-template-columns: 150px 1fr;
|
||||
row-gap: var(--spacing-1);
|
||||
}
|
||||
|
||||
.media-image {
|
||||
--aspect-ratio: 0.8;
|
||||
|
||||
border: 1px solid var(--color-shadow);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
overflow: hidden;
|
||||
|
||||
source,
|
||||
img {
|
||||
aspect-ratio: var(--aspect-ratio);
|
||||
height: auto;
|
||||
object-fit: cover;
|
||||
border-radius: var(--spacing-1);
|
||||
}
|
||||
}
|
||||
|
||||
.media-image--tall {
|
||||
--aspect-ratio: 0.67;
|
||||
}
|
||||
|
||||
.media-meta-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 225px 1fr;
|
||||
}
|
||||
|
||||
.meta-grid--full {
|
||||
grid-column: 1/3;
|
||||
}
|
||||
|
||||
.media-meta {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
@container (max-width: 36rem) {
|
||||
.media-meta-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(var(--column-count), minmax(0, 1fr));
|
||||
grid-gap: var(--spacing-0\.5);
|
||||
grid-gap: var(--spacing-2);
|
||||
|
||||
li {
|
||||
border: 1px solid var(--color-shadow);
|
||||
|
@ -15,6 +15,7 @@
|
|||
color: var(--color-white);
|
||||
|
||||
picture {
|
||||
border-radius: 0;
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
|
@ -62,7 +63,7 @@
|
|||
|
||||
.meta-text {
|
||||
transition-delay: 0.05s;
|
||||
transform: translateY(var(--spacing-1));
|
||||
transform: translateY(var(--spacing-4));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
font-family: var(--font-family-body);
|
||||
font-weight: var(--font-weight-body-regular);
|
||||
line-height: 0.8rem;
|
||||
padding-inline: var(--spacing-0\.5);
|
||||
padding-block: var(--spacing-0\.25);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
padding-inline: var(--spacing-2);
|
||||
padding-block: var(--spacing-1);
|
||||
border-radius: var(--spacing-2);
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ spacing, regardless of their size
|
|||
*/
|
||||
|
||||
.cluster {
|
||||
--gap: var(--spacing-1);
|
||||
--gap: var(--spacing-4);
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--gap, --spacing-1);
|
||||
gap: var(--gap, --spacing-4);
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ there is space in the viewport and stacks on small viewports
|
|||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: var(--spacing-0\.5);
|
||||
gap: var(--spacing-2);
|
||||
}
|
||||
|
||||
.repel[data-nowrap] {
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
html {
|
||||
scrollbar-color: var(--color-primary) var(--color-surface);
|
||||
scrollbar-gutter: stable;
|
||||
scrollbar-width: thin;
|
||||
}
|
||||
|
||||
body {
|
||||
|
@ -50,14 +52,14 @@ h2 {
|
|||
|
||||
h3 {
|
||||
font-size: 1.5rem;
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-weight: var(--font-weight-normal);
|
||||
letter-spacing: -0.05rem;
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 1.125rem;
|
||||
font-weight: var(--font-weight-bold);
|
||||
font-weight: var(--font-weight-normal);
|
||||
letter-spacing: -0.05rem;
|
||||
line-height: 1.125rem;
|
||||
text-transform: uppercase;
|
||||
|
@ -103,9 +105,9 @@ blockquote {
|
|||
border-inline-start: 2px solid var(--color-primary);
|
||||
margin-inline-start: 0;
|
||||
margin-inline-end: 0;
|
||||
padding: var(--spacing-1);
|
||||
padding: var(--spacing-4);
|
||||
background-color: var(--color-surface);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
}
|
||||
|
||||
blockquote > * + * {
|
||||
|
@ -138,7 +140,7 @@ code {
|
|||
|
||||
:not(pre) > code {
|
||||
background-color: var(--color-surface);
|
||||
border-radius: var(--spacing-0\.25);
|
||||
border-radius: var(--spacing-1);
|
||||
padding-block: 0.15em;
|
||||
padding-inline: 0.25em;
|
||||
}
|
||||
|
@ -153,7 +155,7 @@ picture {
|
|||
flex-direction: column;
|
||||
align-items: center;
|
||||
margin-inline: 0;
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
@ -172,20 +174,20 @@ picture img {
|
|||
|
||||
aside {
|
||||
background-color: var(--color-surface);
|
||||
padding: var(--spacing-1);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
margin-inline: calc(-1 * var(--spacing-1));
|
||||
padding: var(--spacing-4);
|
||||
border-radius: var(--spacing-2);
|
||||
margin-inline: calc(-1 * var(--spacing-4));
|
||||
}
|
||||
|
||||
mark {
|
||||
background-color: var(--color-border);
|
||||
color: var(--color-text);
|
||||
padding-block: var(--spacing-0\.25);
|
||||
padding-block: var(--spacing-1);
|
||||
}
|
||||
|
||||
[href="#main"] {
|
||||
background-color: var(--color-background);
|
||||
margin-inline: var(--spacing-1);
|
||||
margin-inline: var(--spacing-4);
|
||||
}
|
||||
|
||||
[href="#main"]:not(:focus) {
|
||||
|
@ -202,7 +204,7 @@ mark {
|
|||
|
||||
table {
|
||||
border: 1px solid var(--color-border);
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
border-spacing: 0;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
@ -218,8 +220,8 @@ table thead th {
|
|||
|
||||
table th,
|
||||
table td {
|
||||
padding-block: var(--spacing-0\.5);
|
||||
padding-inline: var(--spacing-1);
|
||||
padding-block: var(--spacing-2);
|
||||
padding-inline: var(--spacing-4);
|
||||
}
|
||||
|
||||
table tbody tr:first-child td {
|
||||
|
@ -230,6 +232,10 @@ table tbody tr:not(:last-child) td {
|
|||
border-bottom: 1px solid var(--color-border);
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-inline-start: 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Snippet from:
|
||||
* https://nerdy.dev/6-css-snippets-every-front-end-developer-should-know-in-2025#transition-animation-for-%3Cdetails%3E
|
||||
|
|
1
src/includes/css/global/lilypad.css
Normal file
1
src/includes/css/global/lilypad.css
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,8 +1,22 @@
|
|||
@import "global/reset.css";
|
||||
@import "global/variables.css";
|
||||
|
||||
@import "global/global-styles.css";
|
||||
|
||||
@import-glob "blocks/*.css";
|
||||
@import-glob "compositions/*.css";
|
||||
@import-glob "utilities/*.css";
|
||||
@import "blocks/button.css";
|
||||
@import "blocks/card.css";
|
||||
@import "blocks/media-display.css";
|
||||
@import "blocks/media-grid.css";
|
||||
@import "blocks/pill.css";
|
||||
@import "blocks/posts.css";
|
||||
@import "blocks/prism.css";
|
||||
@import "blocks/site-header.css";
|
||||
@import "blocks/site-logo.css";
|
||||
@import "blocks/stars.css";
|
||||
|
||||
@import "compositions/cluster.css";
|
||||
@import "compositions/repel.css";
|
||||
|
||||
@import "utilities/fonts.css";
|
||||
@import "utilities/image.css";
|
||||
@import "utilities/table.css";
|
||||
@import "utilities/wrapper.css";
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.flex-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.items-center {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.items-end {
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.justify-center {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.justify-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.flex-wrap {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.flex-1 {
|
||||
flex: 1;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* FLOW UTILITY
|
||||
* Like the Every Layout stack: https://every-layout.dev/layouts/stack/
|
||||
* Info about this implementation: https://piccalil.li/quick-tip/flow-utility/
|
||||
*/
|
||||
.flow > * + * {
|
||||
margin-block-start: var(--flow-space, 1em);
|
||||
}
|
|
@ -2,22 +2,6 @@
|
|||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.font-size-m {
|
||||
font-size: 1.125rem;
|
||||
}
|
||||
|
||||
.font-size-l {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.font-size-xl {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.font-size-2xl {
|
||||
font-size: 3rem;
|
||||
}
|
||||
|
||||
.line-height-s {
|
||||
line-height: 0.8rem;
|
||||
}
|
||||
|
@ -29,7 +13,3 @@
|
|||
.line-height-l {
|
||||
line-height: 1.5rem;
|
||||
}
|
||||
|
||||
.line-height-xl {
|
||||
line-height: 2rem;
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
.image-shrink {
|
||||
max-width: 50%;
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-tiny {
|
||||
max-width: 25%;
|
||||
border-radius: var(--spacing-0\.5);
|
||||
border-radius: var(--spacing-2);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
.list-none {
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.list-disc {
|
||||
list-style-type: disc;
|
||||
}
|
||||
|
||||
.list-decimal {
|
||||
list-style-type: decimal;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* VISUALLY HIDDEN UTILITY
|
||||
* Info: https://piccalil.li/quick-tip/visually-hidden/
|
||||
*/
|
||||
.visually-hidden {
|
||||
border: 0;
|
||||
clip: rect(0 0 0 0);
|
||||
height: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -20,12 +20,13 @@
|
|||
<script type="module"
|
||||
src="https://cdn.jsdelivr.net/npm/@justinribeiro/lite-youtube@1.4.0/lite-youtube.min.js"></script>
|
||||
{% endif %}
|
||||
{% set css %}
|
||||
<style>{% include "css/global/lilypad.css" %}</style>
|
||||
{% css %}
|
||||
{% include "css/styles.css" %}
|
||||
{% endset %}
|
||||
<style>{{ css | postcss | safe }}</style>
|
||||
{% endcss %}
|
||||
<link rel="stylesheet" href="{% getBundleFileUrl "css" %}">
|
||||
</head>
|
||||
<body class="flex-col">
|
||||
<body class="flex flex-col">
|
||||
{% include "partials/header.html" %}
|
||||
<main id="main" class="flow flex-1 wrapper" tabindex="-1">
|
||||
{{ content | safe }}
|
||||
|
|
|
@ -3,47 +3,43 @@ layout: "layouts/base"
|
|||
---
|
||||
|
||||
{% from "macros/date.njk" import format %}
|
||||
{% from "macros/utils.njk" import stars %}
|
||||
{% from "macros/utils.njk" import stars, spoilerWarning %}
|
||||
{% from "macros/tags.njk" import tagList %}
|
||||
<header class="flow flow-space-1">
|
||||
{{ format(page.date) }}
|
||||
<article class="flow">
|
||||
<header class="flow">
|
||||
<div class="flow flow-space-1">
|
||||
<h1>{{ title }}</h1>
|
||||
{% if pullquote %}<p class="text-fadeText flow-space-0.25">{{ pullquote }}</p>{% endif %}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
<section class="bg-surface radius-0.5 p-1">
|
||||
<span class="text-secondary">{% include "svgs/triangle-exclamation.svg" %}</span>
|
||||
<strong>Warning!</strong>
|
||||
The following may contain spoilers!
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow">
|
||||
{% if pullquote %}<h3 class="text-fadeText">{{ pullquote }}</h3>{% endif %}
|
||||
</div>
|
||||
{{ format(page.date) }}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
{{ spoilerWarning() }}
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow flow-space-default">
|
||||
{{ content | safe }}
|
||||
</section>
|
||||
{% endif %}
|
||||
<hr class="my-2" />
|
||||
<footer class="media-meta-grid gap-1">
|
||||
{% endif %}
|
||||
<footer class="card media-metadata-grid">
|
||||
<div class="media-image media-image--tall">
|
||||
<img src="{{ image }}" alt="" />
|
||||
</div>
|
||||
<div class="flow flex-col justify-center">
|
||||
<div class="flow flex flex-col justify-center flow-space-4">
|
||||
<h2>{{ title }}</h2>
|
||||
{% if subtitle %}<p class="text-fadeText flow-space-0.5 line-height-m">{{ subtitle }}</p>{% endif %}
|
||||
{% if subtitle %}<p class="text-fadeText flow-space-2 line-height-m">{{ subtitle }}</p>{% endif %}
|
||||
{% if rating %}{{ stars(rating) }}{% endif %}
|
||||
<ul class="list-none p-0 mb-0 media-meta gap-0.5">
|
||||
<dl class="media-metadata">
|
||||
{% if author %}
|
||||
<li class="flex-col">
|
||||
<strong>Author</strong><span>{{ author }}</span>
|
||||
</li>
|
||||
<dt><strong>Author</strong></dt>
|
||||
<dd>{{ author }}</dd>
|
||||
{% endif %}
|
||||
{% if year %}
|
||||
<li class="flex-col">
|
||||
<strong>Published</strong><span>{{ year }}</span>
|
||||
</li>
|
||||
<dt><strong>Published</strong></dt>
|
||||
<dd>{{ year }}</dd>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</dl>
|
||||
</div>
|
||||
</footer>
|
||||
<hr class="my-2">
|
||||
{{ tagList(tags | filter("book") , "/books") }}
|
||||
</footer>
|
||||
{{ tagList(tags | filter("book") , "/books") }}
|
||||
</article>
|
||||
|
|
|
@ -3,54 +3,46 @@ layout: "layouts/base"
|
|||
---
|
||||
|
||||
{% from "macros/date.njk" import format %}
|
||||
{% from "macros/utils.njk" import stars %}
|
||||
{% from "macros/utils.njk" import stars, spoilerWarning %}
|
||||
{% from "macros/tags.njk" import tagList %}
|
||||
<header class="flow flow-space-1">
|
||||
{{ format(page.date) }}
|
||||
<article class="flow">
|
||||
<header class="flow">
|
||||
<div class="flow flow-space-1">
|
||||
<h1>{{ title }}</h1>
|
||||
{% if pullquote %}<p class="text-fadeText flow-space-0.25">{{ pullquote }}</p>{% endif %}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
<section class="bg-surface radius-0.5 p-1">
|
||||
<span class="text-secondary">{% include "svgs/triangle-exclamation.svg" %}</span>
|
||||
<strong>Warning!</strong>
|
||||
The following may contain spoilers!
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow">
|
||||
{% if pullquote %}<h3 class="text-fadeText">{{ pullquote }}</h3>{% endif %}
|
||||
</div>
|
||||
{{ format(page.date) }}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
{{ spoilerWarning() }}
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow flow-space-default">
|
||||
{{ content | safe }}
|
||||
</section>
|
||||
{% endif %}
|
||||
<hr class="my-2" />
|
||||
<footer class="media-meta-grid gap-1">
|
||||
{% endif %}
|
||||
<footer class="card media-metadata-grid">
|
||||
<div class="media-image media-image--tall">
|
||||
<img src="{{ image }}" alt="" />
|
||||
</div>
|
||||
<div class="flow flex-col justify-center">
|
||||
<div class="flex items-center gap-0.5 flex-wrap">
|
||||
<div class="flow flex flex-col justify-center flow-space-4">
|
||||
<h2>{{ title }}</h2>
|
||||
</div>
|
||||
{% if subtitle %}<h2>{{ subtitle }}</h2>{% endif %}
|
||||
{% if rating %}{{ stars(rating) }}{% endif %}
|
||||
<ul class="list-none p-0 mb-0 media-meta gap-0.5">
|
||||
<dl class="media-metadata">
|
||||
{% if year %}
|
||||
<li class="flex-col">
|
||||
<strong>Released</strong><span>{{ year }}</span>
|
||||
</li>
|
||||
<dt><strong>Released</strong></dt>
|
||||
<dd>{{ year }}</dd>
|
||||
{% endif %}
|
||||
{% if platform %}
|
||||
<li class="flex-col">
|
||||
<strong>Platform</strong><span>{{ platform }}</span>
|
||||
</li>
|
||||
<dt><strong>Platform</strong></dt>
|
||||
<dd>{{ platform }}</dd>
|
||||
{% endif %}
|
||||
{% if playtime %}
|
||||
<li class="flex-col">
|
||||
<strong>Playtime</strong><span>{{ playtime }}</span>
|
||||
</li>
|
||||
<dt><strong>Playtime</strong></dt>
|
||||
<dd>{{ playtime }}</dd>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</dl>
|
||||
</div>
|
||||
</footer>
|
||||
<hr class="my-2">
|
||||
{{ tagList(tags | filter("game") , "/games") }}
|
||||
</footer>
|
||||
{{ tagList(tags | filter("game") , "/games") }}
|
||||
</article>
|
||||
|
|
|
@ -3,66 +3,59 @@ layout: "layouts/base"
|
|||
---
|
||||
|
||||
{% from "macros/date.njk" import format %}
|
||||
{% from "macros/utils.njk" import stars %}
|
||||
{% from "macros/utils.njk" import stars, spoilerWarning %}
|
||||
{% from "macros/tags.njk" import tagList %}
|
||||
<header class="flow flow-space-1">
|
||||
{{ format(page.date) }}
|
||||
<article class="flow">
|
||||
<header class="flow">
|
||||
<div class="flow flow-space-1">
|
||||
<h1>{{ title }}</h1>
|
||||
<p class="text-fadeText flow-space-0.25">{{ pullquote }}</p>
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
<section class="bg-surface radius-0.5 p-1">
|
||||
<span class="text-secondary">{% include "svgs/triangle-exclamation.svg" %}</span>
|
||||
<strong>Warning!</strong>
|
||||
The following may contain spoilers!
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if watchHistory.length > 1 %}
|
||||
{% if pullquote %}<h3 class="text-fadeText">{{ pullquote }}</h3>{% endif %}
|
||||
</div>
|
||||
{{ format(page.date) }}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
{{ spoilerWarning() }}
|
||||
{% endif %}
|
||||
{% if watchHistory.length > 1 %}
|
||||
<p>
|
||||
<span class="text-primary">{% include "svgs/circle-info.svg" %}</span>
|
||||
I've seen this movie <strong>{{ watchHistory.length }}</strong> {{ "time" | pluralize(watchHistory) }}!
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if favourite or isFavourite %}
|
||||
{% endif %}
|
||||
{% if favourite or isFavourite %}
|
||||
<p>
|
||||
<span class="text-secondary">{% include "svgs/star.svg" %}</span>
|
||||
This is one of my favourite movies!
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow">
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow flow-space-default">
|
||||
{{ content | safe }}
|
||||
</section>
|
||||
{% endif %}
|
||||
<hr class="my-2" />
|
||||
<footer class="media-meta-grid gap-1">
|
||||
{% endif %}
|
||||
<footer class="card media-metadata-grid">
|
||||
<div class="media-image media-image--tall">
|
||||
<img src="{{ image }}" alt="" />
|
||||
</div>
|
||||
<div class="flow flex-col justify-center">
|
||||
<div class="flex items-center gap-0.5 flex-wrap">
|
||||
<div class="flow flex flex-col justify-center flow-space-4">
|
||||
<h2>{{ title }}</h2>
|
||||
</div>
|
||||
{% if subtitle %}<h2>{{ subtitle }}</h2>{% endif %}
|
||||
{% if subtitle %}<p class="text-fadeText flow-space-2 line-height-m">{{ subtitle }}</p>{% endif %}
|
||||
{% if rating %}{{ stars(rating) }}{% endif %}
|
||||
<ul class="list-none p-0 mb-0 media-meta gap-0.5">
|
||||
<dl class="media-metadata">
|
||||
{% if year %}
|
||||
<li class="flex-col">
|
||||
<strong>Released</strong><span>{{ year }}</span>
|
||||
</li>
|
||||
<dt><strong>Released</strong></dt>
|
||||
<dd>{{ year }}</dd>
|
||||
{% endif %}
|
||||
{% if director %}
|
||||
<li class="flex-col">
|
||||
<strong>Director</strong>{{ director }}
|
||||
</li>
|
||||
<dt><strong>Director</strong></dt>
|
||||
<dd>{{ director }}</dd>
|
||||
{% endif %}
|
||||
{% if runtime %}
|
||||
<li class="flex-col">
|
||||
<strong>Runtime</strong><span>{{ runtime }} mins</span>
|
||||
</li>
|
||||
<dt><strong>Runtime</strong></dt>
|
||||
<dd>{{ runtime }} minutes</dd>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</dl>
|
||||
</div>
|
||||
</footer>
|
||||
<hr class="my-2">
|
||||
{{ tagList(tags | filter("movie") , "/watching/movies") }}
|
||||
</footer>
|
||||
{{ tagList(tags | filter("movie") , "/watching/movies") }}
|
||||
</article>
|
||||
|
|
|
@ -3,20 +3,17 @@ layout: "layouts/base"
|
|||
---
|
||||
|
||||
{% from "macros/date.njk" import format %}
|
||||
{% from "macros/tags.njk" import tagList %}
|
||||
<article class="flow">
|
||||
<header class="flow flow-space-1 mb-2">
|
||||
{{ format(page.date) }}
|
||||
<header class="flow">
|
||||
<div class="flow flow-space-1">
|
||||
<h1>{{ title }}</h1>
|
||||
<p class="text-fadeText flow-space-0.25">{{ excerpt }}</p>
|
||||
<ul class="categories cluster list-none p-0 flow-space-2 line-height-m">
|
||||
{% for tag in tags | filter(["post"]) %}
|
||||
<li>
|
||||
<a class="button" href="/tags/{{ tag | slugify }}">
|
||||
{% include "svgs/frame.svg" %}
|
||||
{{ tag }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<h3 class="text-fadeText">{{ excerpt }}</h3>
|
||||
</div>
|
||||
{{ format(page.date) }}
|
||||
</header>
|
||||
<section class="flow flow-space-default">
|
||||
{{ content | safe }}
|
||||
</section>
|
||||
{{ tagList(tags | filter("post") , "/posts") }}
|
||||
</article>
|
||||
|
|
|
@ -3,61 +3,50 @@ layout: "layouts/base"
|
|||
---
|
||||
|
||||
{% from "macros/date.njk" import format %}
|
||||
{% from "macros/utils.njk" import stars %}
|
||||
{% from "macros/utils.njk" import stars, spoilerWarning %}
|
||||
{% from "macros/tags.njk" import tagList %}
|
||||
<header class="flow flow-space-1">
|
||||
{{ format(page.date) }}
|
||||
<article class="flow">
|
||||
<header class="flow">
|
||||
<div class="flow flow-space-1">
|
||||
<h1>{{ title }}</h1>
|
||||
<p class="text-fadeText flow-space-0.25">{{ pullquote }}</p>
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
<section class="bg-surface radius-0.5 p-1">
|
||||
<span class="text-secondary">{% include "svgs/triangle-exclamation.svg" %}</span>
|
||||
<strong>Warning!</strong>
|
||||
The following may contain spoilers!
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow">
|
||||
{% if pullquote %}<h3 class="text-fadeText">{{ pullquote }}</h3>{% endif %}
|
||||
</div>
|
||||
{{ format(page.date) }}
|
||||
</header>
|
||||
{% if hasSpoilers %}
|
||||
{{ spoilerWarning() }}
|
||||
{% endif %}
|
||||
{% if content %}
|
||||
<section class="flow flow-space-default">
|
||||
{{ content | safe }}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if favourite or isFavourite %}
|
||||
{% endif %}
|
||||
{% if favourite or isFavourite %}
|
||||
<p>
|
||||
<span class="text-secondary">{% include "svgs/star.svg" %}</span>
|
||||
This is one of my favourite shows!
|
||||
</p>
|
||||
{% endif %}
|
||||
<hr class="my-2" />
|
||||
<footer class="media-meta-grid gap-1">
|
||||
{% endif %}
|
||||
<footer class="card media-metadata-grid">
|
||||
<div class="media-image media-image--tall">
|
||||
<img src="{{ image }}" alt="" />
|
||||
</div>
|
||||
<div class="flow flex-col justify-center">
|
||||
<div class="flex items-center gap-0.5 flex-wrap">
|
||||
<div class="flow flex flex-col justify-center flow-space-4">
|
||||
<h2>{{ title }}</h2>
|
||||
</div>
|
||||
{% if subtitle %}<h2>{{ subtitle }}</h2>{% endif %}
|
||||
{% if director %}
|
||||
<p class="flex gap-0.5">
|
||||
<span class="text-fadeText">Directed by</span>{{ director }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% if watchHistory %}<p class="flow-space-0.25">{{ format(watchHistory | last) }}</p>{% endif %}
|
||||
{% if subtitle %}<p class="text-fadeText flow-space-2 line-height-m">{{ subtitle }}</p>{% endif %}
|
||||
{% if rating %}{{ stars(rating) }}{% endif %}
|
||||
<ul class="list-none p-0 mb-0 media-meta gap-0.5">
|
||||
{% if watchHistory %}<p class="flow-space-1">{{ format(watchHistory | last) }}</p>{% endif %}
|
||||
<dl class="media-metadata">
|
||||
{% if year %}
|
||||
<li class="flex-col">
|
||||
<strong>Released</strong><span>{{ year }}</span>
|
||||
</li>
|
||||
<dt><strong>Released</strong></dt>
|
||||
<dd>{{ year }}</dd>
|
||||
{% endif %}
|
||||
{% if runtime %}
|
||||
<li class="flex-col">
|
||||
<strong>Runtime</strong><span>{{ runtime }} mins</span>
|
||||
</li>
|
||||
<dt><strong>Runtime</strong></dt>
|
||||
<dd>{{ runtime }} minutes</dd>
|
||||
{% endif %}
|
||||
</ul>
|
||||
</dl>
|
||||
</div>
|
||||
</footer>
|
||||
<hr class="my-2">
|
||||
{{ tagList(tags | filter("tv") , "/watching/shows") }}
|
||||
</footer>
|
||||
{{ tagList(tags | filter("tv") , "/watching/shows") }}
|
||||
</article>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% macro format(dateString) %}
|
||||
<time class="date flex items-center gap-0.5 text-fadeText"
|
||||
<time class="date flex items-center gap-2 text-fadeText"
|
||||
datetime="{{ dateString }}">
|
||||
<span class="text-primary line-height-s">{% include "svgs/calendar.svg" %}</span>{{ dateString | formatDate("MMMM Do YYYY") }}
|
||||
</time>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{% macro grid(data, shape = "vertical") %}
|
||||
<ul class="media-grid {{ shape }} list-none p-0">
|
||||
{% for item in data %}
|
||||
<li class="radius-0.5">
|
||||
<li class="radius-2">
|
||||
<a href="{{ item.url }}">
|
||||
{% if item.data.image %}<img src="{{ item.data.image }}" alt="" />{% endif %}
|
||||
<div class="meta font-size-s line-height-s flex items-end px-0.5 pb-0.5">
|
||||
<div class="meta font-size-s line-height-s flex items-end px-2 pb-2">
|
||||
<span class="meta-text">{{ item.data.title }}</span>
|
||||
</div>
|
||||
</a>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{% endmacro %}
|
||||
{% macro list(posts, format = "MM/DD") %}
|
||||
<ol class="flow p-0" role="list">
|
||||
{% for post in posts %}<li class="flow-space-0.5">{{ one(post, format) }}</li>{% endfor %}
|
||||
{% for post in posts %}<li class="flow-space-2">{{ one(post, format) }}</li>{% endfor %}
|
||||
</ol>
|
||||
{% endmacro %}
|
||||
{% macro yearList(posts, year, format = "MM/DD") %}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{% macro tagList(tags, urlPrefix) %}
|
||||
<ul class="categories cluster list-none p-0 line-height-m">
|
||||
<ul class="categories cluster list-none p-0 line-height-m flow-space-default">
|
||||
{% for tag in tags %}
|
||||
<li>
|
||||
<a class="button" href="{{ urlPrefix }}/tag/{{ tag | slugify }}">
|
||||
|
|
|
@ -11,3 +11,11 @@
|
|||
{% endfor %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro spoilerWarning() %}
|
||||
<section class="bg-surface radius-1 p-4 flow-space-default">
|
||||
<span class="text-secondary">{% include "svgs/triangle-exclamation.svg" %}</span>
|
||||
<strong>Warning!</strong>
|
||||
The following may contain spoilers!
|
||||
</section>
|
||||
{% endmacro %}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<footer class="bg-surface mt-1.5 py-1.5">
|
||||
<footer class="bg-surface mt-8 py-4">
|
||||
<div class="wrapper flow">
|
||||
<div class="repel">
|
||||
<p>© {{ meta.author }} 2018 - 2025.</p>
|
||||
|
@ -13,8 +13,8 @@
|
|||
</nav>
|
||||
</div>
|
||||
<div class="repel">
|
||||
<nav class="flow-space-0.5">
|
||||
<ul class="cluster p-0 m-0 gap-0.5" role="list">
|
||||
<nav class="flow-space-2">
|
||||
<ul class="cluster p-0 m-0 gap-1" role="list">
|
||||
<li>
|
||||
<a href="/feeds"
|
||||
class="button button--alt"
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<header class="navbar py-1 mb-2">
|
||||
<header class="navbar py-4 mb-8">
|
||||
<a href="#main">Skip to content</a>
|
||||
<div class="wrapper">
|
||||
<nav class="repel">
|
||||
<div class="site-logo flex items-center gap-0.5">
|
||||
<div class="site-logo flex items-center gap-2">
|
||||
<a class="logo flex items-center justify-center"
|
||||
aria-label="Go to index"
|
||||
href="{{ meta.url }}">
|
||||
|
|
|
@ -12,27 +12,27 @@ permalink: /
|
|||
<p>
|
||||
I like to <a href="/posts">write</a> about <a href="/games">games</a>, <a href="/books">books</a>, and <a href="/watching/movies/recent">movies</a> to name a few things. There's a lot to explore, and I hope you have fun!
|
||||
</p>
|
||||
<section class="flow-space-2">
|
||||
<section class="flow-space-8">
|
||||
<header class="flow">
|
||||
<h2>Favourite posts</h2>
|
||||
<p class="flow-space-0.25">Hand-picked, curated selection of my favourite posts!</p>
|
||||
<p class="flow-space-1">Hand-picked, curated selection of my favourite posts!</p>
|
||||
</header>
|
||||
{% set favouritePosts = collections.post | filterFavourites | reverse %}
|
||||
{{ list(favouritePosts, "MM/DD/YYYY") }}
|
||||
</section>
|
||||
<section class="flow-space-2">
|
||||
<section class="flow-space-8">
|
||||
<header>
|
||||
<h2>Recent posts</h2>
|
||||
</header>
|
||||
{% set recentPosts = collections.post | reverse | limit(5) %}
|
||||
{{ list(recentPosts, "MM/DD/YYYY") }}
|
||||
</section>
|
||||
<section class="flow-space-2">
|
||||
<section class="flow-space-8">
|
||||
<header class="flow">
|
||||
<h2>Other pages</h2>
|
||||
<p class="flow-space-0.25">Some of my other pages you can check out!</p>
|
||||
<p class="flow-space-1">Some of my other pages you can check out!</p>
|
||||
</header>
|
||||
<ul class="cluster p-0 gap-0.5 list-none" role="list">
|
||||
<ul class="cluster p-0 list-none" role="list">
|
||||
<li>
|
||||
<a href="/about" class="button">About</a>
|
||||
</li>
|
||||
|
|
|
@ -8,8 +8,8 @@ permalink: "books/tag/{{ tag | slugify }}/index.html"
|
|||
|
||||
{% from "macros/media-grid.njk" import grid %}
|
||||
{% set data = collections.booksByTag[tag] | reverse %}
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Books</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Tagged with "{{ tag }}"</p>
|
||||
<p class="text-fadeText flow-space-1">Tagged with "{{ tag }}"</p>
|
||||
</header>
|
||||
{{ grid(data) }}
|
||||
|
|
|
@ -10,6 +10,10 @@ All the changes that are fit to read!
|
|||
|
||||
If preferred, the [commit log is available here][commits].
|
||||
|
||||
## May 29th, 2025
|
||||
|
||||
- I updated my CSS pipeline! [My PR](https://git.cloud.haska.me/wonderfulfrog/wonderfulfrog.com/pulls/4) has more information, if you're curious. tl;dr: I decreased my build times!
|
||||
|
||||
## May 27th, 2025
|
||||
|
||||
- Updated Eleventy to `3.1.0`
|
||||
|
|
|
@ -4,9 +4,9 @@ description: Various ways to get in touch.
|
|||
permalink: "/contact/index.html"
|
||||
---
|
||||
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Contact</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Various ways to get in touch with me on the internet.</p>
|
||||
<p class="text-fadeText flow-space-1">Various ways to get in touch with me on the internet.</p>
|
||||
</header>
|
||||
<section class="flow">
|
||||
<p>Below are my primary methods of contact. They are the ones I monitor most and likely to respond!</p>
|
||||
|
|
|
@ -8,8 +8,8 @@ permalink: "games/tag/{{ tag | slugify }}/index.html"
|
|||
|
||||
{% from "macros/media-grid.njk" import grid %}
|
||||
{% set data = collections.gamesByTag[tag] %}
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Games</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Tagged with "{{ tag }}"</p>
|
||||
<p class="text-fadeText flow-space-1">Tagged with "{{ tag }}"</p>
|
||||
</header>
|
||||
{{ grid(data) }}
|
||||
|
|
|
@ -5,9 +5,9 @@ permalink: "podroll/index.html"
|
|||
---
|
||||
|
||||
{% set data = collections.podcast | reverse %}
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Podroll</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Some podcasts that I enjoy!</p>
|
||||
<p class="text-fadeText flow-space-1">Some podcasts that I enjoy!</p>
|
||||
</header>
|
||||
<section class="flow">
|
||||
{% for item in data %}
|
||||
|
@ -16,7 +16,7 @@ permalink: "podroll/index.html"
|
|||
<h2>{{ item.data.title }}</h2>
|
||||
{% if item.data.isCompleted %}<span class="pill">Completed</span>{% endif %}
|
||||
</div>
|
||||
<p class="flow-space-0.5">{{ item.data.description }}</p>
|
||||
<p class="flow-space-2">{{ item.data.description }}</p>
|
||||
<div class="flex gap-0.5">
|
||||
{% if item.data.url %}<a href="{{ item.data.url }}" target="_blank">Website</a>{% endif %}
|
||||
{% if item.data.rss %}<a href="{{ item.data.rss }}" target="_blank">RSS</a>{% endif %}
|
||||
|
|
|
@ -8,8 +8,8 @@ permalink: "watching/movies/tag/{{ tag | slugify }}/index.html"
|
|||
|
||||
{% from "macros/media-grid.njk" import grid %}
|
||||
{% set data = collections.moviesByTag[tag] | reverse %}
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Movies</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Tagged with "{{ tag }}"</p>
|
||||
<p class="text-fadeText flow-space-1">Tagged with "{{ tag }}"</p>
|
||||
</header>
|
||||
{{ grid(data) }}
|
||||
|
|
|
@ -8,8 +8,8 @@ permalink: "watching/shows/tag/{{ tag | slugify }}/index.html"
|
|||
|
||||
{% from "macros/media-grid.njk" import grid %}
|
||||
{% set data = collections.showsByTag[tag] | reverse %}
|
||||
<header class="flow flow-space-1">
|
||||
<header class="flow flow-space-4">
|
||||
<h1>Shows</h1>
|
||||
<p class="text-fadeText flow-space-0.25">Tagged with "{{ tag }}"</p>
|
||||
<p class="text-fadeText flow-space-1">Tagged with "{{ tag }}"</p>
|
||||
</header>
|
||||
{{ grid(data) }}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue