Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
230e86bf7c | ||
|
|
32b055f328 | ||
|
|
438d1a67e2 | ||
|
|
cd7f525bac | ||
|
|
6933f11630 | ||
|
|
62dab04ee9 | ||
|
|
e60d191e09 | ||
|
|
efe79ff639 | ||
|
|
4be20cccb3 | ||
|
|
aba74f280e | ||
|
|
0125216d96 | ||
|
|
6ee81d8784 | ||
|
|
2bfe616195 | ||
|
|
f9d8123b9d | ||
|
|
c7ef4c701a | ||
|
|
d8f3ea3430 | ||
|
|
a9b96e567e | ||
|
|
bc1a51a4d5 | ||
|
|
16c3ef1e26 | ||
|
|
efe153191a | ||
|
|
8c2c2231ac | ||
|
|
62b1e448ea | ||
|
|
d53198e1aa | ||
|
|
c6ec6b8f48 | ||
|
|
75909355ba | ||
|
|
d5660455bd | ||
|
|
7df4c1ff8e | ||
|
|
d6c2bb9aa9 | ||
|
|
604a6787f4 | ||
|
|
980cd0b3a6 | ||
|
|
5be42a4ff3 | ||
|
|
25c8e56a76 | ||
|
|
8752eeb904 | ||
|
|
b1135beddb | ||
|
|
84160a0574 | ||
|
|
557308f3f9 | ||
|
|
382419e6d6 | ||
|
|
66df77c32c | ||
|
|
a3e0ba5037 | ||
|
|
51d836c71b | ||
|
|
67e70e68ab | ||
|
|
b31e683786 | ||
|
|
1bb26176ba | ||
|
|
a000d1c1b9 | ||
|
|
cf26b06e3d | ||
|
|
5acda53f58 | ||
|
|
f2bc045735 | ||
|
|
3b1c5ffa88 | ||
|
|
0882fcda41 | ||
|
|
7d042abe1d | ||
|
|
f5bbda1f14 | ||
|
|
9999775e44 | ||
|
|
463cabe793 | ||
|
|
4aa7516cb9 | ||
|
|
f49a7faa4d | ||
|
|
2e26cefab2 | ||
|
|
870a6e5e0f | ||
|
|
be364d7644 | ||
|
|
06bcfc1522 | ||
|
|
dd1943bcdd | ||
|
|
bfa91ea19f | ||
|
|
b4fbeffc41 | ||
|
|
25cf8a38ec | ||
|
|
5724f509a0 | ||
|
|
fe6956aaa3 | ||
|
|
846ef7538f | ||
|
|
f8aacdc85d | ||
|
|
776218805a | ||
|
|
91c7f14113 | ||
|
|
8bcdaeff52 | ||
|
|
3e766eb519 | ||
|
|
2ad41daa2e | ||
|
|
7b248c24b9 | ||
|
|
abec70c655 | ||
|
|
2d35768db9 | ||
|
|
30498307c8 | ||
|
|
953f651c4f | ||
|
|
ee0a39333d | ||
|
|
a2fd1cb797 | ||
|
|
9889cf4adb | ||
|
|
a3b9d20dfb | ||
|
|
1a0898c214 | ||
|
|
07bb31111f | ||
|
|
c517bb8d69 | ||
|
|
830c1a4666 | ||
|
|
1a2850ca8c | ||
|
|
96e70dbd2f | ||
|
|
58da634ec7 | ||
|
|
d8049a1f34 | ||
|
|
12ae5f9a4e | ||
|
|
672a03d4e9 | ||
|
|
0e46e65034 | ||
|
|
782912c8a6 | ||
|
|
470a84429c | ||
|
|
05e40f0ea7 | ||
|
|
35841f26fd | ||
|
|
3fc4468d09 | ||
|
|
bbcdb5ee03 | ||
|
|
d663b851c9 | ||
|
|
4ac0441c3d | ||
|
|
f6620e19a4 | ||
|
|
df9b5e4c55 | ||
|
|
f4a32e5292 | ||
|
|
01c0bf00a2 | ||
|
|
ff03344b81 | ||
|
|
e437febdf8 | ||
|
|
21858e5dd3 | ||
|
|
a780e7cc9e | ||
|
|
d0cb1cf7f5 | ||
|
|
cd30f192eb | ||
|
|
d246ba3437 | ||
|
|
7abb27739e | ||
|
|
742d2b9666 | ||
|
|
3ff187ae10 | ||
|
|
0ec803b447 | ||
|
|
1863efa802 | ||
|
|
153a90fb0a | ||
|
|
0a5d393618 | ||
|
|
532424c953 | ||
|
|
9b5ee21bf7 | ||
|
|
33ad5815a7 | ||
|
|
7a30ee3216 | ||
|
|
88562bd766 | ||
|
|
75d3a12bdc | ||
|
|
f488a6aa54 | ||
|
|
8c135a09c7 | ||
|
|
7ede08fd43 | ||
|
|
e80f340642 | ||
|
|
4b43f76ac4 | ||
|
|
54b63df970 | ||
|
|
b40f41a5f7 | ||
|
|
1cf7b8560e | ||
|
|
ba5b01d084 | ||
|
|
feaaeb30b7 | ||
|
|
4af8d68ac9 | ||
|
|
c51e5b502a | ||
|
|
6585b8e74d | ||
|
|
22d4c48b46 | ||
|
|
18989f817f | ||
|
|
5dfaac6820 | ||
|
|
814d4efe8b | ||
|
|
0b0822d21b | ||
|
|
f1c073535d | ||
|
|
4f0a0f3969 | ||
|
|
c4b7faca88 | ||
|
|
68487ad342 | ||
|
|
2b90da7572 | ||
|
|
58be723eef | ||
|
|
72c5904c27 | ||
|
|
e615e6a91f | ||
|
|
a56ca4c03e | ||
|
|
9a483ad27c | ||
|
|
63e225aebc | ||
|
|
60c07e629b | ||
|
|
ff1fa0a966 | ||
|
|
64007ea884 | ||
|
|
1108f38939 | ||
|
|
cddc20ad3d | ||
|
|
3a9095c4e8 | ||
|
|
914243feb9 | ||
|
|
3f9e6727de | ||
|
|
f980c8c682 | ||
|
|
8104cd4520 | ||
|
|
4f38bbfc82 | ||
|
|
56736453fe | ||
|
|
c04993c983 | ||
|
|
ed3a845a55 | ||
|
|
c8ce389065 | ||
|
|
c95b3c080a | ||
|
|
c559aa9154 | ||
|
|
a14753e656 | ||
|
|
82db8f8758 | ||
|
|
d434da450f | ||
|
|
913f8469f3 | ||
|
|
4f12d9c5ac | ||
|
|
e14261bf4d | ||
|
|
073ad660e4 | ||
|
|
c6dcdacbec | ||
|
|
8ab1cb687b | ||
|
|
ac1903c5a1 | ||
|
|
bf677c3cdf | ||
|
|
8adb83d8a8 | ||
|
|
0439f0478d | ||
|
|
ebe2490fd3 | ||
|
|
409ca37f74 | ||
|
|
e129b26e63 | ||
|
|
dc49b1cad5 | ||
|
|
21e3dca187 | ||
|
|
ff9eb09838 | ||
|
|
ce6aa0fb00 | ||
|
|
f89f135f9b | ||
|
|
422a0e45e8 | ||
|
|
191ee1a355 | ||
|
|
43ccb40e0b | ||
|
|
b5aff7207e | ||
|
|
aa9951e68d | ||
|
|
35519d9d4b | ||
|
|
43ae5c489e | ||
|
|
b51e953a1b | ||
|
|
0e14d3ca72 | ||
|
|
50d4b61037 | ||
|
|
73a0278392 | ||
|
|
b241cc14af | ||
|
|
98c00bb1fd | ||
|
|
bfefa33f13 | ||
|
|
89ff36afc7 | ||
|
|
afbf693d3b | ||
|
|
a3ba14abd2 | ||
|
|
e45e9b0f7a | ||
|
|
3e61e004f4 | ||
|
|
58a412f002 | ||
|
|
64db3a2446 | ||
|
|
a03a1b6c52 | ||
|
|
7f5dc28cad | ||
|
|
7e95d9ff16 | ||
|
|
6e3bfd9a08 | ||
|
|
ae056c75bd | ||
|
|
5c786b15d2 | ||
|
|
2c3711fe1e | ||
|
|
f18e2f2078 | ||
|
|
9a566f99ab | ||
|
|
9db3d3b34c | ||
|
|
9249a6e050 | ||
|
|
7d1fe776c7 | ||
|
|
c4b549bc75 | ||
|
|
6203735ff8 | ||
|
|
3848af101b | ||
|
|
25f5d5897b | ||
|
|
fc71c05327 | ||
|
|
d080981f2d | ||
|
|
778d323db9 | ||
|
|
6e33a3baca | ||
|
|
522842c2f0 | ||
|
|
ecd5de37f4 | ||
|
|
4bf8c7e334 | ||
|
|
94716d8e63 | ||
|
|
3249c8305f | ||
|
|
1b4a4bd654 | ||
|
|
8e9a356aea | ||
|
|
ac4f19f9ca | ||
|
|
2139a422a8 | ||
|
|
895eb9b314 | ||
|
|
f142098f1d | ||
|
|
7bf791fdf3 | ||
|
|
ff738388b1 | ||
|
|
863f4bf127 | ||
|
|
5003eda18f | ||
|
|
96049f57ee | ||
|
|
1913d9c46e | ||
|
|
f2face01a7 | ||
|
|
ca8d4a31cd | ||
|
|
42ce6ceb6f |
No files matched your search
@@ -0,0 +1,28 @@
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: node:current
|
||||
environment:
|
||||
REPOSITORY: leecat.art-site
|
||||
GIT_USER: inherentlee
|
||||
GIT_TOKEN:
|
||||
from_secret: GIT_TOKEN
|
||||
commands:
|
||||
- git config credential.helper '!f() { echo username=$GIT_USER; echo "password=$GIT_TOKEN"; };f'
|
||||
- git submodule update --remote --init --merge
|
||||
- npm install
|
||||
- npm run build
|
||||
- apt-get update && apt-get install -y rsync
|
||||
- rsync -uavh _site/ $REPOSITORY --delete --exclude .git
|
||||
- cd $REPOSITORY
|
||||
- git checkout main
|
||||
- git config --global --add safe.directory /drone/src/$REPOSITORY
|
||||
- git add -A
|
||||
- git commit -m "drone build $(TZ=':America/Los_Angeles' date)"
|
||||
- git push
|
||||
@@ -8,5 +8,5 @@ charset = utf-8
|
||||
indent_style = tab
|
||||
indent_size = 2
|
||||
|
||||
[.{yaml,yml,md,njk}]
|
||||
[*.{yaml,yml,md,njk}]
|
||||
indent_style = space
|
||||
@@ -1,5 +1,5 @@
|
||||
# eleventy output
|
||||
_site
|
||||
|
||||
# npm
|
||||
node_modules
|
||||
|
||||
# build
|
||||
_site
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "leecat.art-site"]
|
||||
path = leecat.art-site
|
||||
url = https://heckin.technology/inherentlee/leecat.art-site.git
|
||||
@@ -0,0 +1,23 @@
|
||||
# leecat.art
|
||||
|
||||
Lee Cattarin's personal website, v2. Built on Eleventy.
|
||||
|
||||
## Install
|
||||
|
||||
```sh
|
||||
npm i
|
||||
# or
|
||||
npm install
|
||||
```
|
||||
|
||||
## Run locally
|
||||
|
||||
```sh
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Build website
|
||||
|
||||
```sh
|
||||
npm run build
|
||||
```
|
||||
@@ -0,0 +1,92 @@
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
export default function (eleventyConfig) {
|
||||
// Return the keys used in an object
|
||||
eleventyConfig.addFilter("getKeys", (target) => {
|
||||
return Object.keys(target);
|
||||
});
|
||||
|
||||
/* Exclude all posts with given URLs from a collection list */
|
||||
eleventyConfig.addFilter(
|
||||
"excludeFromCollection",
|
||||
function (collection = [], urls = [this.ctx.page.url]) {
|
||||
return collection.filter((post) => urls.indexOf(post.url) === -1);
|
||||
},
|
||||
);
|
||||
|
||||
/* Filter a collection by a set of tags, returning any that share one or more tags */
|
||||
eleventyConfig.addFilter(
|
||||
"filterByTags",
|
||||
function (collection = [], ...requiredTags) {
|
||||
return collection.filter((post) => {
|
||||
return requiredTags.flat().some((tag) => post.data.tags.includes(tag));
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
/* Return n elements from a list */
|
||||
eleventyConfig.addFilter("head", (collection = [], n) => {
|
||||
if (!Array.isArray(collection) || collection.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (n < 0) {
|
||||
return collection.slice(n);
|
||||
}
|
||||
|
||||
return collection.slice(0, n);
|
||||
});
|
||||
|
||||
/* For <time> elements */
|
||||
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
|
||||
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd");
|
||||
});
|
||||
|
||||
/* What it says on the tin */
|
||||
eleventyConfig.addFilter("randomize", function (array) {
|
||||
// Create a copy of the array to avoid modifying the original
|
||||
let shuffledArray = array.slice();
|
||||
|
||||
// Fisher-Yates shuffle algorithm
|
||||
for (let i = shuffledArray.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[shuffledArray[i], shuffledArray[j]] = [
|
||||
shuffledArray[j],
|
||||
shuffledArray[i],
|
||||
];
|
||||
}
|
||||
|
||||
return shuffledArray;
|
||||
});
|
||||
|
||||
/* Human-readable dates */
|
||||
eleventyConfig.addFilter("readableDate", (dateObj) => {
|
||||
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toLocaleString(
|
||||
DateTime.DATE_FULL,
|
||||
);
|
||||
});
|
||||
|
||||
/* Filter out structural tags */
|
||||
eleventyConfig.addFilter("removeBasicTags", (tags) => {
|
||||
return tags.filter(
|
||||
(tag) =>
|
||||
[
|
||||
"all",
|
||||
"posts",
|
||||
"gallery",
|
||||
"reference",
|
||||
"tagPagination",
|
||||
"blur",
|
||||
].indexOf(tag) === -1,
|
||||
);
|
||||
});
|
||||
|
||||
/* What it says on the tin */
|
||||
eleventyConfig.addFilter("sortAlphabetically", (strings) =>
|
||||
(strings || []).sort((b, a) => b.localeCompare(a)),
|
||||
);
|
||||
|
||||
/* Remove year from image filenames for OG metadata file path */
|
||||
eleventyConfig.addFilter("toOgFilename", (filename) => {
|
||||
return filename.split("/")[1];
|
||||
});
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
<!doctype html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<title>{{ title or metadata.title }}</title>
|
||||
<meta name="description" content="{{ description or metadata.description }}">
|
||||
{# <link rel="alternate" href="/feed/feed.xml" type="application/atom+xml" title="{{ metadata.title }}"> #}
|
||||
|
||||
<meta property="og:title" content="{{ title or metadata.title }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="{{ description or metadata.description }}" />
|
||||
<meta property="og:site_name" content="{{ metadata.title }}" />
|
||||
|
||||
<meta name="generator" content="{{ eleventy.generator }}">
|
||||
|
||||
{# Styles #}
|
||||
<link rel="stylesheet" href="/assets/css/main.css">
|
||||
|
||||
{# Fonts #}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
|
||||
|
||||
{# Icons #}
|
||||
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body>
|
||||
{{ content | safe }}
|
||||
<body>
|
||||
@@ -0,0 +1,45 @@
|
||||
<footer>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="/colophon/"
|
||||
{% if page.url == "/colophon/" %}aria-current="page"{% endif %}>
|
||||
colophon
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="/" title="go home"
|
||||
aria-label="go home | {{ metadata.title }} from {{ metadata.author }}, copyright 2022-2026"
|
||||
{% if page.url == "/" %}aria-current="page"{% endif %}>
|
||||
{{ metadata.title }} from {{ metadata.author }}, © 2022-2026</a>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<a href="https://heckin.technology/inherentlee/leecat.art" title="source code"
|
||||
aria-label="source code" target="_blank" rel="external">
|
||||
src
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<fieldset id="theme">
|
||||
<legend>color scheme</legend>
|
||||
|
||||
<input type="radio" id="theme-light" name="theme" value="light"/>
|
||||
<label class="theme-light" for="theme-light">
|
||||
<i class="fa-regular fa-sun" aria-hidden="true"></i>
|
||||
light
|
||||
</label>
|
||||
|
||||
<input type="radio" id="theme-auto" name="theme" value="auto" checked/>
|
||||
<label class="theme-auto" for="theme-auto">
|
||||
auto
|
||||
</label>
|
||||
|
||||
<input type="radio" id="theme-dark" name="theme" value="dark"/>
|
||||
<label class="theme-dark" for="theme-dark">
|
||||
dark
|
||||
<i class="fa-regular fa-moon" aria-hidden="true"></i>
|
||||
</label>
|
||||
</fieldset>
|
||||
</footer>
|
||||
@@ -0,0 +1,51 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||
|
||||
{% set pageTitle %}{{ title | safe }} | {{ metadata.title }}{% endset %}
|
||||
<title>{{ pageTitle }}</title>
|
||||
<meta name="description" content="{{ description or metadata.description }}">
|
||||
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
|
||||
|
||||
<meta property="og:title" content="{{ pageTitle }}" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:description" content="{{ description or metadata.description }}" />
|
||||
<meta property="og:site_name" content="{{ metadata.title }}" />
|
||||
<meta property="og:url" content="{{ metadata.url }}{{ page.url }}" />
|
||||
{% if image %}
|
||||
<meta property="og:image" content="{{ metadata.url }}/img/{{ image.src | toOgFilename }}" />
|
||||
<meta property="og:image:alt" content="{{ image.alt }}" />
|
||||
{% else %}
|
||||
<meta property="og:image" content="{{ metadata.url }}/favicon.ico" />
|
||||
<meta property="og:image:alt" content="a teal bird icon" />
|
||||
{% endif %}
|
||||
|
||||
<meta name="generator" content="{{ eleventy.generator }}">
|
||||
|
||||
<meta itemprop="ai-content-declaration:version" content="1.0.0">
|
||||
<meta itemprop="ai-content-declaration:level" content="none">
|
||||
|
||||
{# Fonts #}
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
|
||||
|
||||
{# Icons #}
|
||||
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
||||
|
||||
{# Styles #}
|
||||
<style>{% include "css/main.css" %}</style>
|
||||
<style>{% include "css/nav.css" %}</style>
|
||||
<style>{% include "css/pagefind.css" %}</style>
|
||||
<style>{% include "css/highlighting.css" %}</style>
|
||||
<style>{% include "css/print.css" %}</style>
|
||||
|
||||
<style>{% getBundle "css" %}</style>
|
||||
|
||||
{# Scripts #}
|
||||
<script>{% include "js/theme.js" %}</script>
|
||||
<script type="module">{% getBundle "js" %}</script>
|
||||
|
||||
{# Pagefind #}
|
||||
<link href="/pagefind/pagefind-component-ui.css" rel="stylesheet">
|
||||
<script src="/pagefind/pagefind-component-ui.js" type="module"></script>
|
||||
@@ -0,0 +1,26 @@
|
||||
<header>
|
||||
<a href="#main" id="skip" title="skip to main content">
|
||||
<i class="fa-solid fa-forward" aria-hidden="true"></i> skip
|
||||
</a>
|
||||
|
||||
<nav aria-label="main navigation">
|
||||
<ul>
|
||||
{% for entry in collections.all | eleventyNavigation %}
|
||||
<li>
|
||||
<a href="{{ entry.url }}" title="{{ entry.data.label }}"
|
||||
{% if entry.url == page.url %}aria-current="page"{% endif %}>
|
||||
<i class="{{ entry.data.icon }}" aria-hidden="true"></i>
|
||||
<span class="menu-text">{{ entry.title }}</span>
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="dark searchbox" data-pf-theme="dark">
|
||||
<pagefind-searchbox></pagefind-searchbox>
|
||||
</div>
|
||||
<div class="light searchbox">
|
||||
<pagefind-searchbox></pagefind-searchbox>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,17 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{% include "head-content.njk" %}
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.njk" %}
|
||||
|
||||
<main id="main">
|
||||
{{ content | safe }}
|
||||
</main>
|
||||
|
||||
{% include "footer.njk" %}
|
||||
|
||||
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
layout: base.njk
|
||||
---
|
||||
{% css %}{% include "css/lists.css" %}{% endcss %}
|
||||
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
{{ content | safe }}
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
layout: base.njk
|
||||
---
|
||||
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||
|
||||
<heading-anchors content="<i class='fa-solid fa-anchor'></i>" data-pagefind-body>
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
{{ content | safe }}
|
||||
</heading-anchors>
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
layout: post.njk
|
||||
---
|
||||
{% css %}{% include "css/post-toc.css" %}{% endcss %}
|
||||
|
||||
<aside id="toc">
|
||||
<details>
|
||||
<summary><h2>table of contents</h2></summary>
|
||||
{{ content | toc | safe }}
|
||||
</details>
|
||||
</aside>
|
||||
|
||||
{{ content | safe }}
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
layout: base.njk
|
||||
---
|
||||
{% css %}{% include "css/post.css" %}{% endcss %}
|
||||
{% css %}{% include "css/lists.css" %}{% endcss %}
|
||||
{% css %}{% include "css/modal.css" %}{% endcss %}
|
||||
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||
{% js %}{% include "js/modal.js" %}{% endjs %}
|
||||
|
||||
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
||||
<article data-pagefind-body>
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
<div class="post-metadata">
|
||||
<p>
|
||||
posted on
|
||||
<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time>
|
||||
by {{ metadata.author }}
|
||||
</p>
|
||||
{% set relevantTags = tags | removeBasicTags %}
|
||||
{% if relevantTags.length %}
|
||||
<ul class="post-tags">
|
||||
{% for tag in relevantTags %}
|
||||
<li>
|
||||
{% set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
|
||||
<a href="{{ tagUrl }}">{{ tag }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% if image %}
|
||||
<dialog closedby="any" aria-label="image modal" tabindex="-1">
|
||||
<button class="close-dialog" autofocus aria-label="close the image modal">×</button>
|
||||
<img class="modal-img" src="/img/{{ image.src }}" alt="{{ image.alt }}">
|
||||
</dialog>
|
||||
<img class="hero" src="/img/{{ image.src }}" alt="{{ image.alt }}">
|
||||
{% endif %}
|
||||
|
||||
{{ content | safe }}
|
||||
</article>
|
||||
|
||||
{% set olderPost = collections.posts | getPreviousCollectionItem %}
|
||||
{% set newerPost = collections.posts | getNextCollectionItem %}
|
||||
{% set olderHref = olderPost.url %}
|
||||
{% set newerHref = newerPost.url %}
|
||||
{% set olderTitle = olderPost.data.title %}
|
||||
{% set newerTitle = newerPost.data.title %}
|
||||
{% set inPost = true %}
|
||||
{% include "pagination.njk" %}
|
||||
|
||||
<hr>
|
||||
|
||||
{% set relevantTags = tags | removeBasicTags %}
|
||||
{% set postlist = collections.posts | filterByTags(relevantTags) | excludeFromCollection([page.url, olderHref, newerHref]) | randomize | head(3) %}
|
||||
{% if postlist.length %}
|
||||
<section class="related-posts">
|
||||
<h2 data-ha-exclude>related posts</h2>
|
||||
{% include "postlist.njk" %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
</heading-anchors>
|
||||
@@ -0,0 +1,21 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
{% include "head-content.njk" %}
|
||||
|
||||
<meta http-equiv="refresh" content="0; url=/tags/{{ tag }}">
|
||||
</head>
|
||||
<body>
|
||||
{% include "header.njk" %}
|
||||
|
||||
<main id="main">
|
||||
<h1>{{ title }}</h1>
|
||||
|
||||
{{ content | safe }}
|
||||
</main>
|
||||
|
||||
{% include "footer.njk" %}
|
||||
|
||||
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
|
||||
<body>
|
||||
</html>
|
||||
@@ -0,0 +1,20 @@
|
||||
{% if olderHref or newerHref %}
|
||||
<nav aria-label="pagination">
|
||||
<ol class="pagination {% if inPost %}post-pagination{% endif %}">
|
||||
{% if olderHref %}
|
||||
<li class="older">
|
||||
<a href="{{ olderHref }}">
|
||||
<i class="fa-solid fa-hand-point-left" aria-hidden="true"></i> {{ olderTitle or "older" }}
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if newerHref %}
|
||||
<li class="newer">
|
||||
<a href="{{ newerHref }}">
|
||||
{{ newerTitle or "newer" }} <i class="fa-solid fa-hand-point-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ol>
|
||||
</nav>
|
||||
{% endif %}
|
||||
@@ -1,17 +1,18 @@
|
||||
<ol>
|
||||
<ol id="postlist">
|
||||
{% for post in postlist %}
|
||||
<li>
|
||||
<a href="{{ post.url }}">
|
||||
<li class="post">
|
||||
<a class="postlink" href="{{ post.url }}">
|
||||
<h2 data-ha-exclude>{{ post.data.title }} {% if "blur" in post.data.tags %}(mature){% endif %}</h2>
|
||||
{% if post.data.image %}
|
||||
<img src="/img/{{ post.data.image.src }}" alt="{{ post.data.image.alt }}">
|
||||
{% endif %}
|
||||
<h2>{{ post.data.title }}</h2>
|
||||
<ul>
|
||||
{% for tag in post.data.tags %}
|
||||
<ul class="postlist-tags">
|
||||
{% for tag in post.data.tags | removeBasicTags %}
|
||||
<li>{{ tag }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<img src="/img/{{ post.data.image.src }}" alt="{{ post.data.image.alt }}"
|
||||
{% if "blur" in post.data.tags %}class="blur"{% endif %}>
|
||||
{% endif %}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
<ol>
|
||||
</ol>
|
||||
@@ -0,0 +1,25 @@
|
||||
<nav class="webring" aria-labelledby="{{ id }}">
|
||||
<h3 id="{{ id }}">{{ name }}</h3>
|
||||
<p>This site is a member of the <a rel="external" target="_blank" href="{{ url }}">{{ name }}</a>. Navigate through the webring:</p>
|
||||
<ul>
|
||||
<li class="prev">
|
||||
<a rel="external" referrerpolicy="strict-origin" href="{{ prev }}" target="_blank" title="{{ name }} - previous website">
|
||||
<i class="fa-solid fa-hand-point-left" aria-hidden="true"></i>
|
||||
prev
|
||||
</a>
|
||||
</li>
|
||||
<li class="rand">
|
||||
<a rel="external" referrerpolicy="strict-origin" href="{{ rand }}" target="_blank" title="{{ name }} - random website">
|
||||
<i class="fa-solid fa-dice" aria-hidden="true"></i>
|
||||
rand
|
||||
<i class="fa-solid fa-dice" aria-hidden="true"></i>
|
||||
</a>
|
||||
</li>
|
||||
<li class="next">
|
||||
<a rel="external" referrerpolicy="strict-origin" href="{{ next }}" target="_blank" title="{{ name }} - next website">
|
||||
next
|
||||
<i class="fa-solid fa-hand-point-right" aria-hidden="true"></i>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
@@ -0,0 +1,30 @@
|
||||
main {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.rss-explainer {
|
||||
background: var(--color-bg-alt);
|
||||
padding: 1rem;
|
||||
margin-block: 1rem;
|
||||
border-radius: .5rem;
|
||||
}
|
||||
|
||||
.rss-explainer p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.rss-explainer p + p {
|
||||
margin-top: 1.25rem;
|
||||
}
|
||||
|
||||
.feed-url {
|
||||
font-family: var(--font-family-code);
|
||||
font-size: .9rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
p:has(small) {
|
||||
display: block;
|
||||
margin: .25rem 0 0 .75rem;
|
||||
color: var(--color-grey);
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/* Adapted from PrismJS 1.30.0 Tomorrow Night theme
|
||||
https://prismjs.com/download
|
||||
*/
|
||||
code,
|
||||
pre,
|
||||
code[class*=language-],
|
||||
pre[class*=language-] {
|
||||
font-family: var(--font-family-code);
|
||||
background-color: var(--color-bg-alt);
|
||||
font-size: .9em;
|
||||
text-shadow: 0 1px var(--color-shadow);
|
||||
-moz-tab-size: 4;
|
||||
-o-tab-size: 4;
|
||||
tab-size: 4;
|
||||
-webkit-hyphens: none;
|
||||
-moz-hyphens: none;
|
||||
-ms-hyphens: none;
|
||||
hyphens: none;
|
||||
}
|
||||
|
||||
pre,
|
||||
pre[class*=language-] {
|
||||
margin: 1rem 0;
|
||||
padding: 1rem;
|
||||
line-height: 1.5;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-word;
|
||||
overflow-wrap: break-word;
|
||||
border-radius: .5rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
:not(pre)>code,
|
||||
:not(pre)>code[class*=language-] {
|
||||
padding: .2rem;
|
||||
border-radius: .25rem;
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* Selected text */
|
||||
code ::-moz-selection,
|
||||
code::-moz-selection,
|
||||
pre ::-moz-selection,
|
||||
pre::-moz-selection,
|
||||
code[class*=language-] ::-moz-selection,
|
||||
code[class*=language-]::-moz-selection,
|
||||
pre[class*=language-] ::-moz-selection,
|
||||
pre[class*=language-]::-moz-selection,
|
||||
code ::selection,
|
||||
code::selection,
|
||||
pre ::selection,
|
||||
pre::selection,
|
||||
code[class*=language-] ::selection,
|
||||
code[class*=language-]::selection,
|
||||
pre[class*=language-] ::selection,
|
||||
pre[class*=language-]::selection {
|
||||
text-shadow: none;
|
||||
background-color: var(--color-bg);
|
||||
}
|
||||
|
||||
/* Syntax highlighting */
|
||||
.token.namespace {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
.token.bold,
|
||||
.token.important {
|
||||
font-weight:700
|
||||
}
|
||||
|
||||
.token.italic {
|
||||
font-style:italic
|
||||
}
|
||||
|
||||
.token.block-comment,
|
||||
.token.cdata,
|
||||
.token.comment,
|
||||
.token.doctype,
|
||||
.token.prolog,
|
||||
.token.punctuation {
|
||||
color: var(--color-grey);
|
||||
}
|
||||
|
||||
.token.attr-name,
|
||||
.token.deleted,
|
||||
.token.namespace,
|
||||
.token.tag {
|
||||
color: var(--color-red);
|
||||
}
|
||||
|
||||
.token.boolean,
|
||||
.token.function,
|
||||
.token.number {
|
||||
color: var(--color-orange);
|
||||
}
|
||||
|
||||
.token.class-name,
|
||||
.token.constant,
|
||||
.token.property,
|
||||
.token.symbol {
|
||||
color: var(--color-yellow);
|
||||
}
|
||||
|
||||
.token.attr-value,
|
||||
.token.char,
|
||||
.token.regex,
|
||||
.token.string,
|
||||
.token.variable,
|
||||
.token.inserted {
|
||||
color: var(--color-green);
|
||||
}
|
||||
|
||||
.token.entity,
|
||||
.token.operator,
|
||||
.token.url,
|
||||
.token.function-name {
|
||||
color:var(--color-blue);
|
||||
}
|
||||
|
||||
.token.atrule,
|
||||
.token.builtin,
|
||||
.token.important,
|
||||
.token.keyword,
|
||||
.token.selector {
|
||||
color: var(--color-purple);
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
#postlist,
|
||||
#taglist {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
#postlist, .post,
|
||||
#taglist, .tag {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Odd-numbered posts & tag layout/coloration */
|
||||
.post:nth-child(odd) .postlink,
|
||||
.tag:nth-child(odd) .taglink {
|
||||
grid-template-areas:
|
||||
'img h2'
|
||||
'img info'
|
||||
'img .';
|
||||
grid-template-columns: 45% auto;;
|
||||
--color-primary: var(--color-teal);
|
||||
--color-accent: var(--color-pink);
|
||||
}
|
||||
|
||||
/* Even-numbered posts & tags layout/coloration */
|
||||
.post:nth-child(even) .postlink,
|
||||
.tag:nth-child(even) .taglink {
|
||||
grid-template-areas:
|
||||
'h2 img'
|
||||
'info img'
|
||||
'. img';
|
||||
grid-template-columns: auto 45%;
|
||||
--color-primary: var(--color-pink);
|
||||
--color-accent: var(--color-teal);
|
||||
}
|
||||
|
||||
/* Layout for all posts on mobile */
|
||||
@media (max-width: 650px) {
|
||||
.post:nth-child(n) .postlink,
|
||||
.tag:nth-child(n) .taglink {
|
||||
grid-template-areas:
|
||||
'img'
|
||||
'h2'
|
||||
'info';
|
||||
grid-template-columns: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* Link */
|
||||
.postlink,
|
||||
.taglink {
|
||||
display: grid;
|
||||
border: .25rem solid var(--color-primary);
|
||||
border-radius: 1.25rem;
|
||||
box-shadow: .35rem .35rem var(--color-shadow);
|
||||
margin: 2rem 0;
|
||||
text-decoration: none;
|
||||
/* Click animation handling */
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: top .05s ease-in, left .05s ease-in;
|
||||
}
|
||||
|
||||
.postlink:focus-visible,
|
||||
.taglink:focus-visible {
|
||||
background-color: var(--color-primary);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.postlink:hover,
|
||||
.taglink:hover {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* Forced colors */
|
||||
@media (forced-colors: active) {
|
||||
.postlink:focus-visible,
|
||||
.taglink:focus-visible {
|
||||
outline-offset: .25rem;
|
||||
outline: .25rem solid;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.postlink:hover,
|
||||
.taglink:hover {
|
||||
outline-offset: .25rem;
|
||||
outline: .25rem solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Click animation */
|
||||
.postlink:active,
|
||||
.taglink:active {
|
||||
top: .2rem;
|
||||
left: .2rem;
|
||||
box-shadow: .15rem .15rem var(--color-shadow);
|
||||
}
|
||||
|
||||
/* Post & tag elements */
|
||||
.post h2, .post img,
|
||||
.post ul, .post li,
|
||||
.tag h2, .tag p,
|
||||
.tag img {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post h2,
|
||||
.tag h2 {
|
||||
grid-area: h2;
|
||||
padding: .25rem .5rem;
|
||||
text-transform: uppercase;
|
||||
font-family: var(--font-family);
|
||||
font-size: 1.5rem;
|
||||
color: var(--color-primary);
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
border-bottom: .25rem solid var(--color-accent);
|
||||
}
|
||||
|
||||
.post:nth-child(even) h2,
|
||||
.tag:nth-child(even) h2 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.postlink:focus-visible h2,
|
||||
.taglink:focus-visible h2 {
|
||||
color: var(--color-bg);
|
||||
border-color: var(--color-bg);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.postlink:hover h2,
|
||||
.taglink:hover h2 {
|
||||
color: var(--color-bg);
|
||||
border-color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Images */
|
||||
.post img,
|
||||
.tag-imgs {
|
||||
grid-area: img;
|
||||
}
|
||||
|
||||
.blur {
|
||||
filter: blur(.75rem);
|
||||
clip-path: inset(0 round 1rem);
|
||||
}
|
||||
|
||||
.tag-imgs {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
gap: .15rem;
|
||||
}
|
||||
|
||||
.tag-imgs img {
|
||||
aspect-ratio: 3 / 2;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.missing-image {
|
||||
width: 100%;
|
||||
aspect-ratio: 3 / 2;
|
||||
background-color: var(--color-bg-alt);
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.taglink:focus-visible .missing-image {
|
||||
opacity: .7;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.taglink:hover .missing-image {
|
||||
opacity: .7;
|
||||
}
|
||||
}
|
||||
|
||||
/* Post tags */
|
||||
.postlist-tags {
|
||||
grid-area: info;
|
||||
list-style: none;
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: .5rem;
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
.post:nth-child(odd) .postlist-tags {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.postlist-tags li,
|
||||
.tagcount {
|
||||
background-color: var(--color-primary);
|
||||
color: var(--color-bg);
|
||||
padding: 0 .5rem;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.postlink:focus-visible .postlist-tags li,
|
||||
.taglink:focus-visible .tagcount {
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.postlink:hover .postlist-tags li,
|
||||
.taglink:hover .tagcount {
|
||||
background-color: var(--color-bg);
|
||||
color: var(--color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
/* Tag count */
|
||||
.tag p {
|
||||
grid-area: info;
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
.tag:nth-child(odd) p {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -1,12 +1,24 @@
|
||||
@font-face {
|
||||
font-family: "Peritel";
|
||||
src:
|
||||
url("/fonts/Peritel/Peritel-Regular.woff2") format("woff2"),
|
||||
url("/fonts/Peritel/Peritel-Regular.otf") format("opentype");
|
||||
}
|
||||
|
||||
:root {
|
||||
color-scheme: light dark;
|
||||
|
||||
--font-family: 'Atkinson Hyperlegible Next', sans-serif;
|
||||
/* if you change the header font, go to post-toc.css and fuck about with the width
|
||||
of the table of contents */
|
||||
--font-family-headers: 'Peritel', 'Atkinson Hyperlegible Next', sans-serif;
|
||||
--font-family-code: 'Atkinson Hyperlegible Mono', monospace;
|
||||
|
||||
--color-dark: #2e303e;
|
||||
--color-dark-alt: #3c3f52;
|
||||
--color-light: #ebeeef;
|
||||
--color-light-alt: #dbe1e3;
|
||||
|
||||
--color-teal-dark: #18737b;
|
||||
--color-teal-light: #25b0bc;
|
||||
--color-pink-dark: #94195d;
|
||||
@@ -15,7 +27,7 @@
|
||||
--color-shadow: rgba(2, 10, 40, .25);
|
||||
|
||||
/* Used for syntax highlighting */
|
||||
--color-red-light: #e95678;
|
||||
--color-red-light: #f195aa;
|
||||
--color-orange-light: #fab795;
|
||||
--color-yellow-light: #fbe6bc;
|
||||
--color-green-light: #29d398;
|
||||
@@ -49,6 +61,14 @@
|
||||
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
|
||||
}
|
||||
|
||||
:root:has(#theme-light:checked) {
|
||||
color-scheme: light;
|
||||
}
|
||||
:root:has(#theme-dark:checked) {
|
||||
color-scheme: dark;
|
||||
}
|
||||
|
||||
/* Base */
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
@@ -59,6 +79,230 @@ body {
|
||||
font-family: var(--font-family);
|
||||
color: var(--color-text);
|
||||
background-color: var(--color-bg);
|
||||
max-width: 60vw;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 60vw;
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 1100px) {
|
||||
main {
|
||||
width: 75vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
main {
|
||||
width: 92vw;
|
||||
}
|
||||
}
|
||||
|
||||
/* Headers */
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
line-height: 1.25;
|
||||
color: var(--color-teal);
|
||||
font-family: var(--font-family-headers);
|
||||
letter-spacing: 0.1rem;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-top: 3rem;
|
||||
font-size: 3.7rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 2rem;
|
||||
font-size: 2.35rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
h1 {
|
||||
margin-top: 1.5rem;
|
||||
font-size: 2.25rem;
|
||||
}
|
||||
h2 { font-size: 1.8rem; }
|
||||
h3 { font-size: 1.4rem; }
|
||||
}
|
||||
|
||||
h4, h5, h6 {
|
||||
margin-top: 1rem;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
/* Images */
|
||||
img {
|
||||
display: block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
border-radius: 1rem;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Paragraphs */
|
||||
p {
|
||||
margin: 1.25rem 0;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
strong,
|
||||
b {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
a {
|
||||
color: var(--color-text);
|
||||
border-radius: .25rem;
|
||||
text-decoration: underline;
|
||||
text-decoration-style: solid;
|
||||
text-decoration-thickness: .2em;
|
||||
text-decoration-color: var(--color-teal);
|
||||
transition: text-decoration-thickness .5s;
|
||||
}
|
||||
|
||||
a:focus-visible {
|
||||
text-decoration: none;
|
||||
outline: .15rem solid var(--color-teal);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
a:hover {
|
||||
text-decoration-thickness: .4em;
|
||||
}
|
||||
}
|
||||
|
||||
a:active {
|
||||
text-decoration-thickness: .4em;
|
||||
}
|
||||
|
||||
/* Heading anchors */
|
||||
a.ha,
|
||||
span.ha-placeholder {
|
||||
color: var(--color-pink);
|
||||
font-size: .8em;
|
||||
vertical-align: .1em;
|
||||
}
|
||||
span.ha-placeholder {
|
||||
opacity: .55;
|
||||
}
|
||||
|
||||
/* Lists */
|
||||
::marker {
|
||||
color: var(--color-pink);
|
||||
}
|
||||
|
||||
ul, ol, dl, li {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
ul, ol, dl {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
line-height: 1.4;
|
||||
margin-top: .65rem;
|
||||
margin-bottom: .65rem;
|
||||
}
|
||||
|
||||
li ul, li ol {
|
||||
margin: .5rem 0;
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
li ul, li ol {
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
dt {
|
||||
font-weight: 900;
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
dd {
|
||||
margin-left: 2rem;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
/* Blockquotes */
|
||||
blockquote {
|
||||
margin: .5rem 0;
|
||||
padding: 0 1rem;
|
||||
border-radius: .5rem;
|
||||
line-height: 1.25;
|
||||
border-left: .5rem solid var(--color-pink);
|
||||
}
|
||||
|
||||
blockquote,
|
||||
blockquote p,
|
||||
blockquote ol,
|
||||
blockquote ul {
|
||||
background-color: var(--color-bg-alt);
|
||||
padding: .5rem;
|
||||
}
|
||||
|
||||
blockquote p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table {
|
||||
width: 100%;
|
||||
border-spacing: 0; /* border collapse doesn't play nice with radii */
|
||||
border-radius: .3rem;
|
||||
border: thin solid var(--color-pink);
|
||||
margin: 1.25rem 0;
|
||||
}
|
||||
|
||||
th {
|
||||
color: var(--color-bg);
|
||||
background-color: var(--color-pink);
|
||||
}
|
||||
|
||||
th code {
|
||||
color: var(--color-text); /* Yes, I actually do this somewhere */
|
||||
}
|
||||
|
||||
th, td {
|
||||
padding: .5rem;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
tr:nth-child(even) { background-color: var(--color-bg-alt); }
|
||||
th:not(:first-child) { border-left: thin solid var(--color-bg); }
|
||||
th:first-child { border-top-left-radius: .25rem; }
|
||||
th:last-child { border-top-right-radius: .25rem; }
|
||||
td:not(:first-child) { border-left: thin solid var(--color-pink); }
|
||||
|
||||
/* Times */
|
||||
time {
|
||||
color: var(--color-grey);
|
||||
}
|
||||
|
||||
/* Horizontal rules */
|
||||
hr {
|
||||
border: .25rem solid var(--color-pink);
|
||||
margin: 2rem 0;
|
||||
}
|
||||
|
||||
/* Used on home, reference, gallery pages */
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Currently only used for resume, but it's generalizable */
|
||||
.upper {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
img[tabindex="0"] {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
img[tabindex="0"]:focus-visible {
|
||||
outline: .15rem solid var(--color-teal);
|
||||
}
|
||||
|
||||
dialog {
|
||||
margin: auto;
|
||||
flex-flow: column;
|
||||
background: transparent;
|
||||
border: none;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
dialog[open] {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
dialog::backdrop {
|
||||
background-color: rgba(from var(--color-bg) r g b / .8);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
body:has(dialog[open]) {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.close-dialog {
|
||||
background-color: rgba(from var(--color-teal) r g b / .35);
|
||||
font-size: 1.5rem;
|
||||
padding: 0 .5rem .15rem;
|
||||
border-radius: 1rem;
|
||||
color: var(--color-teal);
|
||||
box-shadow: .15rem .15rem var(--color-shadow);
|
||||
border: .08rem solid var(--color-teal);
|
||||
align-self: flex-end;
|
||||
justify-self: flex-start;
|
||||
margin: 0 .1rem;
|
||||
/* Click animation handling */
|
||||
position: relative;
|
||||
top: 1rem;
|
||||
left: -.15rem;
|
||||
transition: top .1s ease-in, left .1s ease-in;
|
||||
}
|
||||
|
||||
.close-dialog:focus-visible {
|
||||
outline: none;
|
||||
background-color: var(--color-teal);
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.close-dialog:hover {
|
||||
outline: none;
|
||||
background-color: var(--color-teal);
|
||||
color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.close-dialog:focus-visible {
|
||||
outline-offset: .08rem;
|
||||
outline: .08rem solid;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.close-dialog:hover {
|
||||
outline-offset: .08rem;
|
||||
outline: .08rem solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Click animation */
|
||||
.close-dialog:active {
|
||||
top: 1.1rem;
|
||||
left: -.05rem;
|
||||
box-shadow: .05rem .05rem var(--color-shadow);
|
||||
}
|
||||
|
||||
.modal-img {
|
||||
max-height: calc(100vh - 2rem);
|
||||
object-fit: contain;
|
||||
width: auto;
|
||||
max-width: 90%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
@@ -0,0 +1,397 @@
|
||||
/* Header */
|
||||
header {
|
||||
background-color: var(--color-bg);
|
||||
padding: .75rem 0;
|
||||
border-bottom: thick solid var(--color-teal);
|
||||
box-shadow: 0 .25rem .15rem var(--color-shadow);
|
||||
display: grid;
|
||||
grid-template-columns: auto;
|
||||
}
|
||||
|
||||
/* Header links, pagination links */
|
||||
header a,
|
||||
.pagination a,
|
||||
.webring ul a {
|
||||
border-radius: 1rem;
|
||||
border: .125rem solid var(--color-pink);
|
||||
color: var(--color-pink);
|
||||
text-decoration: none;
|
||||
padding: 0 .25rem;
|
||||
box-shadow: .15rem .15rem var(--color-shadow);
|
||||
font-size: 1.2rem;
|
||||
/* Click animation handling */
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: top .05s ease-in, left .05s ease-in;
|
||||
}
|
||||
|
||||
header a,
|
||||
.pagination .older a,
|
||||
.webring .prev a,
|
||||
.webring .rand a {
|
||||
padding-right: .35rem;
|
||||
}
|
||||
|
||||
.pagination .newer a,
|
||||
.webring .next a,
|
||||
.webring .rand a {
|
||||
padding-left: .35rem;
|
||||
}
|
||||
|
||||
header a:focus-visible,
|
||||
.pagination a:focus-visible,
|
||||
.webring ul a:focus-visible {
|
||||
color: var(--color-bg);
|
||||
border-color: var(--color-pink);
|
||||
background-color: var(--color-pink);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
header a:hover,
|
||||
.pagination a:hover,
|
||||
.webring ul a:hover {
|
||||
color: var(--color-bg);
|
||||
border-color: var(--color-pink);
|
||||
background-color: var(--color-pink);
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
header a:focus-visible,
|
||||
.pagination a:focus-visible,
|
||||
.webring ul a:focus-visible {
|
||||
outline-offset: .125rem;
|
||||
outline: .125rem solid;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
header a:hover,
|
||||
.pagination a:hover,
|
||||
.webring ul a:hover {
|
||||
outline-offset: .125rem;
|
||||
outline: .125rem solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Click animation */
|
||||
header a:active,
|
||||
.pagination a:active,
|
||||
.webring ul a:active {
|
||||
top: .1rem;
|
||||
left: .1rem;
|
||||
box-shadow: .05rem .05rem var(--color-shadow);
|
||||
}
|
||||
|
||||
/* Current page */
|
||||
header a[aria-current="page"] {
|
||||
border-color: var(--color-teal);
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
header a[aria-current="page"]:focus-visible {
|
||||
color: var(--color-bg);
|
||||
border-color: var(--color-teal);
|
||||
background-color: var(--color-teal);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
header a[aria-current="page"]:hover {
|
||||
color: var(--color-bg);
|
||||
background-color: var(--color-teal);
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
}
|
||||
|
||||
/* Header link icons, pagination icons */
|
||||
header i,
|
||||
.pagination i,
|
||||
.webring ul i {
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
header i,
|
||||
.pagination .older i,
|
||||
.webring .prev i,
|
||||
.webring .rand i:nth-child(1) {
|
||||
padding-left: .25rem;
|
||||
}
|
||||
|
||||
.pagination .newer i,
|
||||
.webring .next i,
|
||||
.webring .rand i:nth-child(2) {
|
||||
padding-right: .25rem;
|
||||
}
|
||||
|
||||
header a[aria-current="page"] i {
|
||||
color: var(--color-pink);
|
||||
}
|
||||
|
||||
header a:focus-visible i,
|
||||
a[aria-current="page"] a:focus-visible i,
|
||||
.pagination a:focus-visible i,
|
||||
.webring ul a:focus-visible i {
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
header a:hover i,
|
||||
header a[aria-current="page"]:hover i,
|
||||
.pagination a:hover i,
|
||||
.webring ul a:hover i {
|
||||
color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip link */
|
||||
#skip {
|
||||
left: -999px;
|
||||
position: absolute;
|
||||
top: auto;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
overflow: hidden;
|
||||
z-index: -99;
|
||||
}
|
||||
|
||||
#skip:focus-visible {
|
||||
display: inline-block;
|
||||
left: auto;
|
||||
top: auto;
|
||||
width: auto;
|
||||
height: auto;
|
||||
overflow: auto;
|
||||
margin: -.125rem 10%;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
/* Nav */
|
||||
header ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
gap: 1rem;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
header ul,
|
||||
header li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.menu-text {
|
||||
display: none; /* Icons only on small screens */
|
||||
}
|
||||
|
||||
header a {
|
||||
padding: .15rem .5rem;
|
||||
}
|
||||
|
||||
header i {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
footer {
|
||||
padding: 1rem 0;
|
||||
font-size: .9rem;
|
||||
border-top: thick solid var(--color-pink);
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
footer ul {
|
||||
display: flex;
|
||||
list-style: none;
|
||||
gap: .5rem;
|
||||
justify-content: center;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
footer li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
footer li:nth-child(2)::before,
|
||||
footer li:nth-child(2)::after {
|
||||
content: " ● " / "";
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
footer ul {
|
||||
flex-flow: column;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
footer li:nth-child(2)::before,
|
||||
footer li:nth-child(2)::after {
|
||||
content: none;
|
||||
}
|
||||
}
|
||||
|
||||
footer a {
|
||||
text-decoration-color: var(--color-pink);
|
||||
}
|
||||
|
||||
footer a:focus-visible {
|
||||
outline-color: var(--color-pink);
|
||||
}
|
||||
|
||||
/* color picker */
|
||||
#theme {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
margin: .5rem auto 0;
|
||||
padding: 0 .75rem .5rem;
|
||||
width: fit-content;
|
||||
border: .125rem solid var(--color-teal);
|
||||
border-radius: 2rem;
|
||||
}
|
||||
|
||||
#theme legend {
|
||||
margin: 0 auto;
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
footer label {
|
||||
cursor: pointer;
|
||||
border: .125rem solid var(--color-pink);
|
||||
padding: 0 .25rem;
|
||||
color: var(--color-pink);
|
||||
background-color: var(--color-bg); /* this stops the box shadows from showing through */
|
||||
box-shadow: .15em .15em var(--color-shadow);
|
||||
/* Click animation handling */
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: top .05s ease-in, left .05s ease-in;
|
||||
}
|
||||
|
||||
footer input:checked + label {
|
||||
color: var(--color-blue);
|
||||
border-color: var(--color-blue);
|
||||
}
|
||||
|
||||
footer label i {
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
footer input:checked + label i {
|
||||
color: var(--color-pink);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
footer label:hover,
|
||||
footer input:checked + label:hover,
|
||||
footer label:hover i,
|
||||
footer input:checked + label:hover i {
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
footer label:hover {
|
||||
background-color: var(--color-pink);
|
||||
}
|
||||
|
||||
footer input:checked + label:hover {
|
||||
background-color: var(--color-teal);
|
||||
}
|
||||
}
|
||||
|
||||
footer input:focus-visible + label,
|
||||
footer input:focus-visible + label i {
|
||||
color: var(--color-bg);
|
||||
background-color: var(--color-pink);
|
||||
border-color: var(--color-pink);
|
||||
}
|
||||
|
||||
footer input:checked:focus-visible + label,
|
||||
footer input:checked:focus-visible + label i {
|
||||
color: var(--color-bg);
|
||||
background-color: var(--color-teal);
|
||||
border-color: var(--color-teal);
|
||||
}
|
||||
|
||||
footer label:active {
|
||||
top: .09em;
|
||||
left: .09em;
|
||||
box-shadow: .05em .05em var(--color-shadow);
|
||||
}
|
||||
|
||||
label.theme-light {
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 1rem;
|
||||
border-right: none;
|
||||
padding-left: .35rem;
|
||||
}
|
||||
|
||||
label.theme-auto {
|
||||
}
|
||||
|
||||
label.theme-dark {
|
||||
border-top-right-radius: 1rem;
|
||||
border-bottom-right-radius: 1rem;
|
||||
border-left: none;
|
||||
padding-right: .35rem;
|
||||
}
|
||||
|
||||
footer input {
|
||||
/* To allow screen reader to still access these. */
|
||||
/* From https://lyra.horse/blog/2025/08/you-dont-need-js/ */
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Pagination */
|
||||
.pagination,
|
||||
.pagination li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-areas: "older newer";
|
||||
list-style: none;
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.post-pagination {
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"older"
|
||||
"newer";
|
||||
gap: .75rem;
|
||||
}
|
||||
}
|
||||
|
||||
.pagination .older {
|
||||
grid-area: older;
|
||||
}
|
||||
|
||||
.pagination .newer {
|
||||
grid-area: newer;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* webring navigation */
|
||||
.webring {
|
||||
margin-bottom: 3rem;
|
||||
}
|
||||
|
||||
.webring ul {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
list-style: none;
|
||||
justify-content: center;
|
||||
gap: .5rem;
|
||||
}
|
||||
|
||||
.webring ul,
|
||||
.webring li {
|
||||
margin-left: 0;
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
/* Handle color schemes */
|
||||
:root:has(#theme-light:checked) .dark {
|
||||
display: none;
|
||||
}
|
||||
:root:has(#theme-dark:checked) .light {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root:not(:has(#theme-dark:checked)) .dark {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root:not(:has(#theme-light:checked)) .light {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.searchbox {
|
||||
margin: 1rem auto 0;
|
||||
}
|
||||
|
||||
pagefind-searchbox {
|
||||
/* Shadows */
|
||||
--pf-scroll-shadow: var(--color-shadow) !important;
|
||||
--pf-shadow-sm: .15rem .15rem 0 var(--color-shadow) !important;
|
||||
--pf-shadow-md: .25rem .25rem 0 var(--color-shadow) !important;
|
||||
--pf-shadow-lg: 1rem 1rem 0 var(--color-shadow) !important;
|
||||
|
||||
/* Typography */
|
||||
--pf-font: var(--font-family) !important;
|
||||
|
||||
/* Border */
|
||||
--pf-border-radius: 1.5rem !important;
|
||||
|
||||
/* Focus */
|
||||
--pf-outline-width: .125rem !important;
|
||||
--pf-outline-offset: 0 !important;
|
||||
|
||||
/* Width */
|
||||
--pf-searchbox-max-width: min(550px, 92vw) !important;
|
||||
}
|
||||
|
||||
.light pagefind-searchbox {
|
||||
--pf-text: var(--color-dark) !important;
|
||||
--pf-text-secondary: var(--color-dark-alt) !important;
|
||||
--pf-text-muted: var(--color-dark-alt) !important;
|
||||
--pf-background: var(--color-light-alt) !important;
|
||||
--pf-border: var(--color-pink-dark) !important;
|
||||
--pf-border-focus: var(--color-pink-dark) !important;
|
||||
--pf-skeleton: var(--color-light) !important;
|
||||
--pf-skeleton-shine: var(--color-dark) !important;
|
||||
--pf-hover: var(--color-light) !important;
|
||||
--pf-mark: var(--color-teal-dark) !important;
|
||||
--pf-outline-focus: var(--color-teal-dark) !important;
|
||||
|
||||
/* Error */
|
||||
--pf-error-bg: var(--color-light-alt) !important;
|
||||
--pf-error-border: var(--color-red-dark) !important;
|
||||
--pf-error-text: var(--color-red-dark) !important;
|
||||
--pf-error-text-secondary: var(--color-red-dark) !important;
|
||||
}
|
||||
|
||||
.dark pagefind-searchbox {
|
||||
--pf-text: var(--color-light) !important;
|
||||
--pf-text-secondary: var(--color-light-alt) !important;
|
||||
--pf-text-muted: var(--color-light-alt) !important;
|
||||
--pf-background: var(--color-dark-alt) !important;
|
||||
--pf-border: var(--color-pink-light) !important;
|
||||
--pf-border-focus: var(--color-pink-light) !important;
|
||||
--pf-skeleton: var(--color-dark) !important;
|
||||
--pf-skeleton-shine: var(--color-dark) !important;
|
||||
--pf-hover: var(--color-dark) !important;
|
||||
--pf-mark: var(--color-teal-light) !important;
|
||||
--pf-outline-focus: var(--color-teal-light) !important;
|
||||
|
||||
/* Error */
|
||||
--pf-error-bg: var(--color-dark-alt) !important;
|
||||
--pf-error-border: var(--color-red-light) !important;
|
||||
--pf-error-text: var(--color-red-light) !important;
|
||||
--pf-error-text-secondary: var(--color-red-light) !important;
|
||||
}
|
||||
|
||||
pagefind-searchbox input {
|
||||
border-width: .125rem !important;
|
||||
}
|
||||
|
||||
pagefind-searchbox input:not(:focus-visible) {
|
||||
box-shadow: var(--pf-shadow-md) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 650px) {
|
||||
.pf-trigger-shortcut {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.pf-searchbox-dropdown,
|
||||
.pf-searchbox-footer {
|
||||
border-width: .125rem !important;
|
||||
}
|
||||
|
||||
.pf-error {
|
||||
margin-top: .5rem !important;
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
.color {
|
||||
border: .125rem solid var(--color-text);
|
||||
border-radius: 2rem;
|
||||
padding: .5rem;
|
||||
text-align: center;
|
||||
width: 65%;
|
||||
margin: 1rem auto;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#dark,
|
||||
#dark-alt,
|
||||
#teal-dark,
|
||||
#pink-dark {
|
||||
color: var(--color-light);
|
||||
}
|
||||
|
||||
#light,
|
||||
#light-alt,
|
||||
#teal-light,
|
||||
#pink-light {
|
||||
color: var(--color-dark);
|
||||
}
|
||||
|
||||
#dark { background-color: var(--color-dark); }
|
||||
#dark-alt { background-color: var(--color-dark-alt); }
|
||||
#light { background-color: var(--color-light); }
|
||||
#light-alt { background-color: var(--color-light-alt); }
|
||||
#teal-dark { background-color: var(--color-teal-dark); }
|
||||
#teal-light { background-color: var(--color-teal-light); }
|
||||
#pink-dark { background-color: var(--color-pink-dark); }
|
||||
#pink-light { background-color: var(--color-pink-light); }
|
||||
@@ -0,0 +1,103 @@
|
||||
#toc {
|
||||
float: right;
|
||||
margin: 1rem 0 1.5rem 1.5rem;
|
||||
width: fit-content;
|
||||
max-width: 55%;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
#toc {
|
||||
float: unset;
|
||||
margin-top: 2rem;
|
||||
margin-left: .5rem;
|
||||
width: calc(100% - .5rem);
|
||||
max-width: unset;
|
||||
}
|
||||
}
|
||||
|
||||
#toc details {
|
||||
border: thick solid var(--color-pink);
|
||||
border-radius: 1rem;
|
||||
margin-top: 1rem;
|
||||
background-color: var(--color-bg);
|
||||
}
|
||||
|
||||
#toc summary {
|
||||
position: relative;
|
||||
top: -1.5rem;
|
||||
left: -.75rem;
|
||||
width: fit-content;
|
||||
background: var(--color-bg);
|
||||
border-radius: .5rem;
|
||||
cursor: pointer;
|
||||
padding-inline-end: .25rem;
|
||||
}
|
||||
|
||||
#toc summary:focus-visible {
|
||||
outline: .15rem solid var(--color-teal);
|
||||
}
|
||||
|
||||
#toc summary::marker {
|
||||
font-size: 2.35rem;
|
||||
}
|
||||
|
||||
#toc h2 {
|
||||
margin-top: 0;
|
||||
display: inline;
|
||||
line-height: normal;
|
||||
}
|
||||
|
||||
#toc nav {
|
||||
position: relative;
|
||||
top: -1.25rem;
|
||||
}
|
||||
|
||||
/* `tree` style toc */
|
||||
#toc nav > ol {
|
||||
margin-inline: 1rem;
|
||||
}
|
||||
|
||||
#toc ol {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#toc li {
|
||||
position: relative;
|
||||
padding-inline-start: 1em;
|
||||
list-style: none;
|
||||
margin-block: 0;
|
||||
margin-left: .35rem;
|
||||
}
|
||||
|
||||
#toc li::before,
|
||||
#toc li::after {
|
||||
display: block;
|
||||
position: absolute;
|
||||
box-sizing: border-box;
|
||||
inset-block: 0 auto;
|
||||
inset-inline: 0 auto;
|
||||
inline-size: .75em;
|
||||
border-inline-start: .1rem solid var(--color-pink);
|
||||
}
|
||||
|
||||
#toc li::before {
|
||||
block-size: .5lh;
|
||||
border-block-end: .1rem solid var(--color-pink);
|
||||
content: "";
|
||||
}
|
||||
|
||||
#toc li:not(:last-child)::after {
|
||||
block-size: 100%;
|
||||
content: "";
|
||||
}
|
||||
|
||||
/* underlines are unnecessary in this context */
|
||||
#toc a {
|
||||
text-decoration: none;
|
||||
color: var(--color-blue);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#toc a:focus-visible {
|
||||
outline-color: var(--color-pink);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
.post-metadata {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
margin: 1.5rem 0 .5rem;
|
||||
}
|
||||
|
||||
.post-metadata p {
|
||||
font-size: .9rem;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post-tags {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
gap: .5rem;
|
||||
list-style: none;
|
||||
margin: 0;
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.post-tags li {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.post-tags li a {
|
||||
text-decoration: none;
|
||||
color: var(--color-teal);
|
||||
padding: 0 .5rem;
|
||||
border-radius: 1rem;
|
||||
box-shadow: .15rem .15rem var(--color-shadow);
|
||||
border: .08rem solid var(--color-teal);
|
||||
line-height: 2;
|
||||
/* Click animation handling */
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transition: top .1s ease-in, left .1s ease-in;
|
||||
}
|
||||
|
||||
.post-tags li a:focus-visible {
|
||||
outline: none;
|
||||
background-color: var(--color-teal);
|
||||
color: var(--color-bg);
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.post-tags li a:hover {
|
||||
outline: none;
|
||||
background-color: var(--color-teal);
|
||||
color: var(--color-bg);
|
||||
}
|
||||
}
|
||||
|
||||
@media (forced-colors: active) {
|
||||
.post-tags li a:focus-visible {
|
||||
outline-offset: .08rem;
|
||||
outline: .08rem solid;
|
||||
}
|
||||
|
||||
@media (any-hover: hover) {
|
||||
.post-tags li a:hover {
|
||||
outline-offset: .08rem;
|
||||
outline: .08rem solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Click animation */
|
||||
.post-tags li a:active {
|
||||
top: .1rem;
|
||||
left: .1rem;
|
||||
box-shadow: .05rem .05rem var(--color-shadow);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
@media print {
|
||||
/* Nav elements */
|
||||
header,
|
||||
footer,
|
||||
nav {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Base */
|
||||
body {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
main {
|
||||
width: 95vw;
|
||||
}
|
||||
|
||||
h1,h2,h3,h4,h5,h6 {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
/* Links */
|
||||
/* Hover is not really necessary, but it's annoying when testing otherwise */
|
||||
a,
|
||||
a:hover {
|
||||
text-decoration-style: dotted;
|
||||
text-decoration-thickness: .1rem;
|
||||
text-decoration-color: #000;
|
||||
}
|
||||
|
||||
a::after{
|
||||
content: " (" attr(href) ")";
|
||||
}
|
||||
|
||||
|
||||
/* Code */
|
||||
code,
|
||||
pre,
|
||||
code[class*=language-],
|
||||
pre[class*=language-] {
|
||||
text-shadow: none;
|
||||
background-color: var(--color-light);
|
||||
color: #000 !important;
|
||||
}
|
||||
|
||||
.token.namespace {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.token.block-comment,
|
||||
.token.cdata,
|
||||
.token.comment,
|
||||
.token.doctype,
|
||||
.token.prolog,
|
||||
.token.punctuation,
|
||||
.token.attr-name,
|
||||
.token.deleted,
|
||||
.token.namespace,
|
||||
.token.tag,
|
||||
.token.boolean,
|
||||
.token.function,
|
||||
.token.number,
|
||||
.token.class-name,
|
||||
.token.constant,
|
||||
.token.property,
|
||||
.token.symbol,
|
||||
.token.attr-value,
|
||||
.token.char,
|
||||
.token.regex,
|
||||
.token.string,
|
||||
.token.variable,
|
||||
.token.inserted,
|
||||
.token.entity,
|
||||
.token.operator,
|
||||
.token.url,
|
||||
.token.function-name,
|
||||
.token.atrule,
|
||||
.token.builtin,
|
||||
.token.important,
|
||||
.token.keyword,
|
||||
.token.selector {
|
||||
color: #000;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
.resume h1 {
|
||||
margin-top: 2rem;
|
||||
font-size: 2.8rem;
|
||||
}
|
||||
|
||||
.resume h2 {
|
||||
margin: 1.7rem 0 1rem;
|
||||
font-size: 1.9rem;
|
||||
}
|
||||
|
||||
.resume h3 {
|
||||
margin: 0;
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.two-col {
|
||||
display: flex;
|
||||
flex-flow: row wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.col2 {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
margin: 1rem 0;
|
||||
border-top: solid var(--color-teal);
|
||||
}
|
||||
|
||||
.job-details p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.job-details a {
|
||||
font-size: 1rem;
|
||||
font-family: var(--font-family);
|
||||
}
|
||||
|
||||
.job p {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.job li strong:not(a) {
|
||||
color: var(--color-teal);
|
||||
}
|
||||
|
||||
.testimonial {
|
||||
font-style: italic;
|
||||
text-align: right;
|
||||
color: var(--color-teal);
|
||||
/* reset some of the default bq styling */
|
||||
border-left: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
margin-top: 0;
|
||||
}
|
||||
@@ -1,15 +1,97 @@
|
||||
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
|
||||
import { HtmlBasePlugin } from "@11ty/eleventy";
|
||||
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
|
||||
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
|
||||
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
|
||||
|
||||
import toc from "eleventy-plugin-nesting-toc";
|
||||
|
||||
import { attrs } from "@mdit/plugin-attrs";
|
||||
import { markdownitLinkAttributes } from 'markdown-it-link-attributes';
|
||||
import markdownitIdAttributes from "markdown-it-anchor";
|
||||
|
||||
import path from "node:path";
|
||||
import { execSync } from 'child_process';
|
||||
import { chunk } from "lodash-es";
|
||||
|
||||
import pluginFilters from "./_config/filters.js";
|
||||
|
||||
export default async function(eleventyConfig) {
|
||||
/* Passthroughs */
|
||||
eleventyConfig.addPassthroughCopy({"css": "assets/css"});
|
||||
/* Markdown HTML attribute parsing */
|
||||
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(attrs));
|
||||
|
||||
/* Markdown apply target="_blank" to all external links */
|
||||
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitLinkAttributes, {
|
||||
matcher(href) {
|
||||
return href.match(/^https?:\/\//);
|
||||
},
|
||||
attrs: {
|
||||
target: "_blank",
|
||||
rel: "external",
|
||||
},
|
||||
}));
|
||||
|
||||
/* Markdown apply ID attributes to headers */
|
||||
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitIdAttributes, {
|
||||
level: [2, 3, 4],
|
||||
tabIndex: false,
|
||||
}));
|
||||
|
||||
/* Bundles */
|
||||
/* CSS */
|
||||
eleventyConfig.addBundle("css", {
|
||||
toFileDirectory: "dist",
|
||||
bundleHtmlContentFromSelector: "style",
|
||||
});
|
||||
|
||||
/* Javascript */
|
||||
eleventyConfig.addBundle("js", {
|
||||
toFileDirectory: "dist",
|
||||
bundleHtmlContentFromSelector: "script",
|
||||
});
|
||||
|
||||
/* Collections */
|
||||
/* Tag pagination */
|
||||
eleventyConfig.addCollection("tagPagination", function(collection) {
|
||||
let tagSet = new Set(collection.getAllSorted().flatMap((post) => post.data.tags || []));
|
||||
tagSet = tagSet.difference(new Set(["posts", "gallery", "reference", "blur"]));
|
||||
|
||||
let paginationSize = 13;
|
||||
let tagMap = [];
|
||||
let tagArray = [...tagSet];
|
||||
|
||||
for( let tagName of tagArray) {
|
||||
let tagItems = collection.getFilteredByTag(tagName);
|
||||
let pagedItems = chunk(tagItems.reverse(), paginationSize); // console.log( tagName, tagItems.length, pagedItems.length );
|
||||
|
||||
for( let pageNumber = 0, max = pagedItems.length; pageNumber < max; pageNumber++) {
|
||||
tagMap.push({
|
||||
tagName: tagName,
|
||||
pageNumber: pageNumber,
|
||||
pageSize: pagedItems.length,
|
||||
pageData: pagedItems[pageNumber]
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return tagMap;
|
||||
});
|
||||
|
||||
/* Passthrough */
|
||||
eleventyConfig
|
||||
.addPassthroughCopy("favicon.ico")
|
||||
.addPassthroughCopy("fonts")
|
||||
.addPassthroughCopy("robots.txt");
|
||||
|
||||
/* Plugins */
|
||||
/* All filters from _config/filters.js */
|
||||
eleventyConfig.addPlugin(pluginFilters);
|
||||
|
||||
/* RSS */
|
||||
eleventyConfig.addPlugin(feedPlugin, {
|
||||
type: "atom", // or "rss", "json"
|
||||
outputPath: "/feed.xml",
|
||||
stylesheet: "/feed.xsl",
|
||||
collection: {
|
||||
name: "posts", // iterate over `collections.posts`
|
||||
limit: 10, // 0 means no limit
|
||||
@@ -26,13 +108,16 @@ export default async function(eleventyConfig) {
|
||||
}
|
||||
});
|
||||
|
||||
/* HTML base */
|
||||
eleventyConfig.addPlugin(HtmlBasePlugin);
|
||||
|
||||
/* Images */
|
||||
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
|
||||
// output image formats
|
||||
formats: ["auto"],
|
||||
|
||||
// output image widths
|
||||
widths: [800],
|
||||
widths: [1000],
|
||||
|
||||
// optional, attributes assigned on <img> nodes override these values
|
||||
htmlOptions: {
|
||||
@@ -41,16 +126,57 @@ export default async function(eleventyConfig) {
|
||||
decoding: "async",
|
||||
},
|
||||
},
|
||||
filenameFormat: function (hash, src, width, format, options) {
|
||||
// If you're building multiple widths
|
||||
// const extension = path.extname(src);
|
||||
// const name = path.basename(src, extension);
|
||||
|
||||
// return `${name}-${width}.${extension}`;
|
||||
return path.basename(src);
|
||||
},
|
||||
});
|
||||
|
||||
/* Navigation */
|
||||
eleventyConfig.addPlugin(eleventyNavigationPlugin);
|
||||
|
||||
/* Syntax highlighting */
|
||||
eleventyConfig.addPlugin(syntaxHighlight);
|
||||
|
||||
/* Table of contents */
|
||||
eleventyConfig.addPlugin(toc);
|
||||
|
||||
/* Draft handling */
|
||||
eleventyConfig.addPreprocessor("drafts", "*", (data, content) => {
|
||||
if (data.draft) {
|
||||
data.title = `${data.title} (draft)`;
|
||||
}
|
||||
|
||||
if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
/* Shortcodes */
|
||||
eleventyConfig.addShortcode("currentBuildDate", () => {
|
||||
return (new Date()).toISOString();
|
||||
});
|
||||
|
||||
/* Watch when serving */
|
||||
eleventyConfig.addWatchTarget("css");
|
||||
eleventyConfig.addWatchTarget("js");
|
||||
|
||||
/* Implement search */
|
||||
/* From https://rknight.me/blog/using-pagefind-with-eleventy-for-search/ */
|
||||
eleventyConfig.on('eleventy.after', () => {
|
||||
execSync(`npx pagefind --site _site --glob \"**/*.html\"`, { encoding: 'utf-8' })
|
||||
});
|
||||
};
|
||||
|
||||
export const config = {
|
||||
dir: {
|
||||
input: "src",
|
||||
includes: "../_includes",
|
||||
layouts: "../_includes/layouts",
|
||||
data: "../_data"
|
||||
},
|
||||
markdownTemplateEngine: "njk",
|
||||
|
||||
|
After Width: | Height: | Size: 18 KiB |
@@ -0,0 +1,33 @@
|
||||
# End User License Agreement (EULA)
|
||||
|
||||
This End User License Agreement is a legal agreement between the licensee (you), and the author of this font, Christopher Kirk-Nielsen.
|
||||
|
||||
You are granted a perpetual, non-exclusive license to use the font with your purchase.
|
||||
|
||||
## By downloading or purchasing this font, you agree to the following terms:
|
||||
|
||||
**For use on a website**
|
||||
Use on any website owned or under the licensee's control, no pageview limits.
|
||||
|
||||
**For use in an app**
|
||||
App embed allowed for 1 app. Another app = another license.
|
||||
|
||||
**Distribution**
|
||||
The font may not be redistributed.
|
||||
|
||||
**Personal modification**
|
||||
The font may be modified for personal use, but cannot be redistributed.
|
||||
|
||||
**Do not use the font for hateful purposes**
|
||||
The font is not allowed to be used in any material promoting hate speech of any kind, including but not limited to: racism, xenophobia, homophobia, sexism, or other types of discrimination.
|
||||
|
||||
**Do not use the font with AI**
|
||||
The font is not allowed to be used in, or in training of, AI/LLMs.
|
||||
|
||||
**Use at your own risk**
|
||||
Any usage of the fonts are at the licensee's own risk.
|
||||
|
||||
For ebooks and other commercial use, or any other specific needs, email me to figure something out: chriskirknielsen+fonts[at]gmail.com
|
||||
|
||||
Thank you very much for the support!
|
||||
Christopher Kirk-Nielsen (https://chriskirknielsen.com/fonts/)
|
||||
@@ -0,0 +1,24 @@
|
||||
/* don't even bother on mobile */
|
||||
if (window.innerWidth > 650) {
|
||||
const dialog = document.querySelector("dialog");
|
||||
const closeButton = document.querySelector(".close-dialog");
|
||||
const hero = document.querySelector(".hero");
|
||||
|
||||
hero.tabIndex = 0;
|
||||
|
||||
hero.addEventListener("click", (e) => dialog.showModal());
|
||||
hero.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
dialog.showModal();
|
||||
}
|
||||
});
|
||||
|
||||
closeButton.addEventListener("click", (e) => dialog.close());
|
||||
closeButton.addEventListener("keydown", (e) => {
|
||||
if (e.key === "Enter" || e.key === " ") {
|
||||
e.preventDefault();
|
||||
dialog.close();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
const THEME = "theme";
|
||||
|
||||
const saveTheme = (themeValue) => {
|
||||
localStorage.setItem(THEME, themeValue);
|
||||
};
|
||||
|
||||
const themeLight = document.getElementById("theme-light");
|
||||
themeLight.addEventListener("input", (e) => {
|
||||
saveTheme(themeLight.value);
|
||||
});
|
||||
|
||||
const themeAuto = document.getElementById("theme-auto");
|
||||
themeAuto.addEventListener("input", (e) => {
|
||||
saveTheme(themeAuto.auto);
|
||||
});
|
||||
|
||||
const themeDark = document.getElementById("theme-dark");
|
||||
themeDark.addEventListener("input", (e) => {
|
||||
saveTheme(themeDark.value);
|
||||
});
|
||||
|
||||
var currentThemeValue = localStorage.getItem(THEME);
|
||||
switch (currentThemeValue) {
|
||||
case "light":
|
||||
themeLight.checked = true;
|
||||
themeAuto.checked = false;
|
||||
break;
|
||||
case "dark":
|
||||
themeDark.checked = true;
|
||||
themeAuto.checked = false;
|
||||
break;
|
||||
case "auto":
|
||||
default:
|
||||
themeAuto.checked = true;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
# check for mogrify
|
||||
which mogrify > /dev/null
|
||||
if [[ $? -ne 0 ]]
|
||||
then
|
||||
echo "mogrify not found, run the following:"
|
||||
echo "sudo apt install imagemagick"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# finds pattern [number]x[number]
|
||||
REGEX="([0-9]+)x[0-9]+"
|
||||
MAX_WIDTH=1200
|
||||
|
||||
for FILE in $(find src/img)
|
||||
do
|
||||
# skip directories
|
||||
if [ -d $FILE ]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
# `identify` prints out file info incl. dimensions in pixels
|
||||
if [[ $(identify $FILE) =~ $REGEX ]]
|
||||
then
|
||||
# regex capture groups
|
||||
WIDTH=${BASH_REMATCH[1]}
|
||||
|
||||
# resize if too large
|
||||
if (( $WIDTH > $MAX_WIDTH ))
|
||||
then
|
||||
echo "resizing $FILE with width $WIDTH"
|
||||
mogrify -resize 1200x $FILE
|
||||
fi
|
||||
fi
|
||||
done
|
||||
@@ -2,9 +2,9 @@
|
||||
"name": "leecat.art",
|
||||
"version": "1.0.0",
|
||||
"description": "Lee's personal website, take 2, built with 11ty",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"serve": "rm -rf _site && npx @11ty/eleventy --serve"
|
||||
"build": "rm -rf _site && npx @11ty/eleventy --quiet",
|
||||
"dev": "rm -rf _site && npx @11ty/eleventy --serve --quiet --output _site"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Lee Cattarin",
|
||||
@@ -13,6 +13,18 @@
|
||||
"devDependencies": {
|
||||
"@11ty/eleventy": "^3.1.2",
|
||||
"@11ty/eleventy-img": "^6.0.4",
|
||||
"@11ty/eleventy-plugin-rss": "^2.0.4"
|
||||
"@11ty/eleventy-navigation": "^1.0.5",
|
||||
"@11ty/eleventy-plugin-bundle": "^3.0.7",
|
||||
"@11ty/eleventy-plugin-rss": "^2.0.4",
|
||||
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
|
||||
"@mdit/plugin-attrs": "^0.24.2",
|
||||
"@zachleat/heading-anchors": "https://github.com/lee0c/heading-anchors/tarball/main",
|
||||
"cheerio": "^1.2.0",
|
||||
"eleventy-plugin-nesting-toc": "^1.3.0",
|
||||
"lodash-es": "^4.17.23",
|
||||
"luxon": "^3.7.2",
|
||||
"markdown-it-anchor": "^10.0.0",
|
||||
"markdown-it-link-attributes": "https://github.com/lee0c/markdown-it-link-attributes/tarball/main",
|
||||
"pagefind": "^1.5.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
# Sourced from https://codeberg.org/superseriousbusiness/gotosocial/
|
||||
|
||||
# AI scrapers and the like.
|
||||
# https://github.com/ai-robots-txt/ai.robots.txt/
|
||||
User-agent: AddSearchBot
|
||||
User-agent: AI2Bot
|
||||
User-agent: AI2Bot-DeepResearchEval
|
||||
User-agent: Ai2Bot-Dolma
|
||||
User-agent: aiHitBot
|
||||
User-agent: amazon-kendra
|
||||
User-agent: Amazonbot
|
||||
User-agent: AmazonBuyForMe
|
||||
User-agent: Andibot
|
||||
User-agent: Anomura
|
||||
User-agent: anthropic-ai
|
||||
User-agent: Applebot
|
||||
User-agent: Applebot-Extended
|
||||
User-agent: atlassian-bot
|
||||
User-agent: Awario
|
||||
User-agent: bedrockbot
|
||||
User-agent: bigsur.ai
|
||||
User-agent: Bravebot
|
||||
User-agent: Brightbot 1.0
|
||||
User-agent: BuddyBot
|
||||
User-agent: Bytespider
|
||||
User-agent: CCBot
|
||||
User-agent: Channel3Bot
|
||||
User-agent: ChatGLM-Spider
|
||||
User-agent: ChatGPT Agent
|
||||
User-agent: ChatGPT-User
|
||||
User-agent: Claude-SearchBot
|
||||
User-agent: Claude-User
|
||||
User-agent: Claude-Web
|
||||
User-agent: ClaudeBot
|
||||
User-agent: Cloudflare-AutoRAG
|
||||
User-agent: CloudVertexBot
|
||||
User-agent: cohere-ai
|
||||
User-agent: cohere-training-data-crawler
|
||||
User-agent: Cotoyogi
|
||||
User-agent: Crawl4AI
|
||||
User-agent: Crawlspace
|
||||
User-agent: Datenbank Crawler
|
||||
User-agent: DeepSeekBot
|
||||
User-agent: Devin
|
||||
User-agent: Diffbot
|
||||
User-agent: DuckAssistBot
|
||||
User-agent: Echobot Bot
|
||||
User-agent: EchoboxBot
|
||||
User-agent: FacebookBot
|
||||
User-agent: facebookexternalhit
|
||||
User-agent: Factset_spyderbot
|
||||
User-agent: FirecrawlAgent
|
||||
User-agent: FriendlyCrawler
|
||||
User-agent: Gemini-Deep-Research
|
||||
User-agent: Google-CloudVertexBot
|
||||
User-agent: Google-Extended
|
||||
User-agent: Google-Firebase
|
||||
User-agent: Google-NotebookLM
|
||||
User-agent: GoogleAgent-Mariner
|
||||
User-agent: GoogleOther
|
||||
User-agent: GoogleOther-Image
|
||||
User-agent: GoogleOther-Video
|
||||
User-agent: GPTBot
|
||||
User-agent: iAskBot
|
||||
User-agent: iaskspider
|
||||
User-agent: iaskspider/2.0
|
||||
User-agent: IbouBot
|
||||
User-agent: ICC-Crawler
|
||||
User-agent: ImagesiftBot
|
||||
User-agent: imageSpider
|
||||
User-agent: img2dataset
|
||||
User-agent: ISSCyberRiskCrawler
|
||||
User-agent: Kangaroo Bot
|
||||
User-agent: KlaviyoAIBot
|
||||
User-agent: KunatoCrawler
|
||||
User-agent: laion-huggingface-processor
|
||||
User-agent: LAIONDownloader
|
||||
User-agent: LCC
|
||||
User-agent: LinerBot
|
||||
User-agent: Linguee Bot
|
||||
User-agent: LinkupBot
|
||||
User-agent: Manus-User
|
||||
User-agent: meta-externalagent
|
||||
User-agent: Meta-ExternalAgent
|
||||
User-agent: meta-externalfetcher
|
||||
User-agent: Meta-ExternalFetcher
|
||||
User-agent: meta-webindexer
|
||||
User-agent: MistralAI-User
|
||||
User-agent: MistralAI-User/1.0
|
||||
User-agent: MyCentralAIScraperBot
|
||||
User-agent: netEstate Imprint Crawler
|
||||
User-agent: NotebookLM
|
||||
User-agent: NovaAct
|
||||
User-agent: OAI-SearchBot
|
||||
User-agent: omgili
|
||||
User-agent: omgilibot
|
||||
User-agent: OpenAI
|
||||
User-agent: Operator
|
||||
User-agent: PanguBot
|
||||
User-agent: Panscient
|
||||
User-agent: panscient.com
|
||||
User-agent: Perplexity-User
|
||||
User-agent: PerplexityBot
|
||||
User-agent: PetalBot
|
||||
User-agent: PhindBot
|
||||
User-agent: Poggio-Citations
|
||||
User-agent: Poseidon Research Crawler
|
||||
User-agent: QualifiedBot
|
||||
User-agent: QuillBot
|
||||
User-agent: quillbot.com
|
||||
User-agent: SBIntuitionsBot
|
||||
User-agent: Scrapy
|
||||
User-agent: SemrushBot-OCOB
|
||||
User-agent: SemrushBot-SWA
|
||||
User-agent: ShapBot
|
||||
User-agent: Sidetrade indexer bot
|
||||
User-agent: Spider
|
||||
User-agent: TerraCotta
|
||||
User-agent: Thinkbot
|
||||
User-agent: TikTokSpider
|
||||
User-agent: Timpibot
|
||||
User-agent: TwinAgent
|
||||
User-agent: VelenPublicWebCrawler
|
||||
User-agent: WARDBot
|
||||
User-agent: Webzio-Extended
|
||||
User-agent: webzio-extended
|
||||
User-agent: wpbot
|
||||
User-agent: WRTNBot
|
||||
User-agent: YaK
|
||||
User-agent: YandexAdditional
|
||||
User-agent: YandexAdditionalBot
|
||||
User-agent: YouBot
|
||||
User-agent: ZanistaBot
|
||||
Disallow: /
|
||||
|
||||
# Marketing/SEO "intelligence" data scrapers
|
||||
User-agent: AwarioRssBot
|
||||
User-agent: AwarioSmartBot
|
||||
User-agent: DataForSeoBot
|
||||
User-agent: magpie-crawler
|
||||
User-agent: Meltwater
|
||||
User-agent: peer39_crawler
|
||||
User-agent: peer39_crawler/1.0
|
||||
User-agent: PiplBot
|
||||
User-agent: scoop.it
|
||||
User-agent: Seekr
|
||||
Disallow: /
|
||||
|
||||
# Rules for everything else
|
||||
User-agent: *
|
||||
Crawl-delay: 500
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
permalink: feed.xml
|
||||
eleventyExcludeFromCollections: true
|
||||
---
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="{{ metadata.language or page.lang }}">
|
||||
<title>{{ metadata.title }}</title>
|
||||
<subtitle>{{ metadata.description }}</subtitle>
|
||||
<link href="{{ permalink | htmlBaseUrl(metadata.base) }}" rel="self" />
|
||||
<link href="{{ metadata.base | addPathPrefixToFullUrl }}" />
|
||||
<updated>{{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }}</updated>
|
||||
<id>{{ metadata.base | addPathPrefixToFullUrl }}</id>
|
||||
<author>
|
||||
<name>{{ metadata.author.name }}</name>
|
||||
</author>
|
||||
{%- for post in collections.posts | reverse %}
|
||||
{%- set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.base) }}{% endset %}
|
||||
<entry>
|
||||
<title>{{ post.data.title }}</title>
|
||||
<link href="{{ absolutePostUrl }}" />
|
||||
<updated>{{ post.date | dateToRfc3339 }}</updated>
|
||||
<id>{{ absolutePostUrl }}</id>
|
||||
<content type="html">{{ post.content | renderTransforms(post.data.page, metadata.base) }}</content>
|
||||
</entry>
|
||||
{%- endfor %}
|
||||
</feed>
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
layout: page-lists.njk
|
||||
pagination:
|
||||
data: collections["gallery"]
|
||||
size: 13
|
||||
reverse: true
|
||||
alias: postlist
|
||||
eleventyNavigation:
|
||||
key: gallery
|
||||
order: 2
|
||||
title: gallery
|
||||
icon: fa-regular fa-images
|
||||
label: view the gallery
|
||||
---
|
||||
|
||||
<p class="centered">the gallery section is for finished art</p>
|
||||
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
|
||||
|
||||
{% include "postlist.njk" %}
|
||||
|
||||
{# idk why these are backwards either #}
|
||||
{% set newerHref = pagination.href.previous %}
|
||||
{% set olderHref = pagination.href.next %}
|
||||
{% include "pagination.njk" %}
|
||||
|
After Width: | Height: | Size: 236 KiB |
|
After Width: | Height: | Size: 227 KiB |
|
After Width: | Height: | Size: 428 KiB |
|
After Width: | Height: | Size: 642 KiB |
|
After Width: | Height: | Size: 389 KiB |
|
After Width: | Height: | Size: 192 KiB |
|
After Width: | Height: | Size: 488 KiB |
|
After Width: | Height: | Size: 195 KiB |
|
After Width: | Height: | Size: 411 KiB |
|
After Width: | Height: | Size: 428 KiB |
|
After Width: | Height: | Size: 241 KiB |
|
After Width: | Height: | Size: 485 KiB |
|
After Width: | Height: | Size: 389 KiB |
|
After Width: | Height: | Size: 266 KiB |
|
After Width: | Height: | Size: 265 KiB |
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 366 KiB |
|
After Width: | Height: | Size: 466 KiB |
|
After Width: | Height: | Size: 260 KiB |
|
After Width: | Height: | Size: 376 KiB |
|
After Width: | Height: | Size: 424 KiB |
|
After Width: | Height: | Size: 944 KiB |
|
After Width: | Height: | Size: 526 KiB |
|
After Width: | Height: | Size: 568 KiB |
|
After Width: | Height: | Size: 299 KiB |
|
After Width: | Height: | Size: 435 KiB |
|
After Width: | Height: | Size: 292 KiB |
|
After Width: | Height: | Size: 682 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 672 KiB |
|
After Width: | Height: | Size: 364 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 344 KiB |
|
After Width: | Height: | Size: 486 KiB |
|
After Width: | Height: | Size: 495 KiB |
|
After Width: | Height: | Size: 548 KiB |
|
After Width: | Height: | Size: 744 KiB |
|
After Width: | Height: | Size: 507 KiB |
|
After Width: | Height: | Size: 409 KiB |
|
After Width: | Height: | Size: 767 KiB |
|
After Width: | Height: | Size: 459 KiB |
|
After Width: | Height: | Size: 529 KiB |
|
After Width: | Height: | Size: 388 KiB |
|
After Width: | Height: | Size: 407 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 597 KiB |
|
After Width: | Height: | Size: 340 KiB |
|
After Width: | Height: | Size: 892 KiB |
|
After Width: | Height: | Size: 396 KiB |
|
After Width: | Height: | Size: 191 KiB |
|
After Width: | Height: | Size: 816 KiB |
|
After Width: | Height: | Size: 781 KiB |
|
After Width: | Height: | Size: 478 KiB |
|
After Width: | Height: | Size: 590 KiB |
|
After Width: | Height: | Size: 423 KiB |