ok big chunk o' everything

This commit is contained in:
2026-09-17 19:41:44 -07:00
parent bf95c6b05e
commit 03398543ee
72 changed files with 870 additions and 54 deletions
+25
View File
@@ -0,0 +1,25 @@
kind: pipeline
type: docker
name: default
steps:
- name: build
image: node:current
environment:
REPOSITORY: siblinghood-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
-1
View File
@@ -1,3 +1,2 @@
_live
_site _site
node_modules node_modules
+2 -2
View File
@@ -1,5 +1,5 @@
<name of project> Siblinghood of the Traveling Greeting Card
Copyright (C) 2026 Lee Cattarin Copyright (C) 2025-2026 Lee Cattarin
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as it under the terms of the GNU Affero General Public License as
+1 -3
View File
@@ -1,6 +1,4 @@
# 11ty Template # Siblinghood of the Traveling Greeting Card
Template repository for my 11ty projects.
## full drone/submodule setup from scratch ## full drone/submodule setup from scratch
+3 -3
View File
@@ -1,6 +1,6 @@
export default { export default {
title: "", title: "siblinghood of the traveling greeting card",
description: "", description: "help a greeting card travel the world",
url: "", url: "https://siblinghood.quest",
author: "Lee Cattarin", author: "Lee Cattarin",
}; };
+15
View File
@@ -0,0 +1,15 @@
<ol>
{% for stop in stops %}
<li class="stop">
<svg aria-hidden="true" viewBox="0 0 32 32" focusable="false">
<circle stroke="none" cx="16" cy="16" r="10"></circle>
</svg>
<h2>{{ stop.data.location }}</h2>
{% if stop.data.img %}
<img src="/img/{{ stop.data.img.src }}" alt="{{ stop.data.img.alt }}">
{% else %}
<div class="spacer"></div>
{% endif %}
</li>
{% endfor %}
</ol>
+4
View File
@@ -1,2 +1,6 @@
<footer> <footer>
<p>brought to you in 2026 by
<a href="https://leecat.art" target="_blank">lee</a>
</p>
<p><a href="/attribution">attribution</a></p>
</footer> </footer>
+11 -8
View File
@@ -1,6 +1,6 @@
<head> <head>
{% if title %} {% if title %}
{% set pageTitle %}{{ title }} | {{ metadata.title }}{% endset %} {% set pageTitle %}{{ title | safe }} | {{ metadata.title }}{% endset %}
{% else %} {% else %}
{% set pageTitle = metadata.title %} {% set pageTitle = metadata.title %}
{% endif %} {% endif %}
@@ -18,21 +18,24 @@
<meta property="og:url" content="{{ metadata.url }}{{ page.url }}" /> <meta property="og:url" content="{{ metadata.url }}{{ page.url }}" />
<meta property="og:description" content="{{ metadata.description }}" /> <meta property="og:description" content="{{ metadata.description }}" />
{#
<link rel="icon" type="image/x-icon" href="/favicon.ico"> <link rel="icon" type="image/x-icon" href="/favicon.ico">
<meta property="og:image" content="" /> <meta property="og:image" content="{{ metadata.url }}/img/logo-light.png" />
<meta property="og:image:alt" content="" /> <meta property="og:image:alt" content="blue and gold icon showing a greeting card with wings" />
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
#}
<meta name="generator" content="{{ eleventy.generator }}"> <meta name="generator" content="{{ eleventy.generator }}">
<!-- 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">
<!-- CSS --> <!-- CSS -->
<style>{% include "css/main.css" %}</style> <style>{% include "css/main.css" %}</style>
<style>{% include "css/nav.css" %}</style>
<style>{% include "css/cards.css" %}</style>
<style>{% getBundle "css" %}</style> <style>{% getBundle "css" %}</style>
{#
<!-- JS --> <!-- JS -->
<script>{% include "js/dropdown.js" %}</script>
<script type="module">{% getBundle "js" %}</script> <script type="module">{% getBundle "js" %}</script>
#}
</head> </head>
+19
View File
@@ -1,4 +1,23 @@
<header> <header>
<nav> <nav>
<a id="skip" href="#main">skip to main</a>
<a href="/" {% if "/" == page.url %}aria-current="page"{% endif %}>home</a>
<div id="dropdown">
<button id="drop-button" aria-label="card submenu" aria-expanded="false"
type="button" aria-controls="drop-content">cards ⮷</button>
<ul id="drop-content" aria-hidden="true">
{% for entry in collections.all | eleventyNavigation %}
<li>
<a href="{{ entry.url }}" {% if entry.url == page.url %}aria-current="page"{% endif %}>
{{ entry.title }}
</a>
</li>
{% endfor %}
</ul>
</div>
</nav> </nav>
<img id="logo-light" src="/img/logo-light.png" alt="blue and gold icon showing a greeting card with wings" />
<img id="logo-dark" src="/img/logo-dark.png" alt="blue and gold icon showing a greeting card with wings" />
</header> </header>
-7
View File
@@ -1,7 +0,0 @@
---
layout: base.njk
---
<h1>{{ title }}</h1>
{{ content | safe }}
+65
View File
@@ -0,0 +1,65 @@
.card {
color: var(--color-accent);
}
p .card {
text-transform: uppercase;
font-weight: 700;
}
ol + p {
margin-top: 1.5rem;
}
.stop {
color: var(--color-accent);
position: relative;
list-style: none;
padding-left: 1.5rem;
}
.stop:not(:last-child) {
padding-bottom: 2rem;
}
.stop:before {
background-color: var(--color-accent);
width: .1rem;
content: '';
position: absolute;
top: 0;
bottom: 0;
left: 0;
}
svg {
margin-left: -2.2rem;
width: 2rem;
fill: var(--color-accent);
float: left;
padding: .4rem .5rem 0 0;
}
@media (max-width: 650px) {
svg {
padding-top: .2rem;
}
}
.stop h2 {
margin: 0;
}
.stop img {
width: 100%;
}
.stop p {
margin: 0;
color: var(--color-text);
padding-top: .5rem;
}
.stop .spacer {
height: 1rem;
}
+148 -2
View File
@@ -1,5 +1,14 @@
:root { :root {
color-scheme: light dark; color-scheme: light dark;
--color-blue-light: #c8e5f5;
--color-gold-light: #ecd399;
--color-blue-dark: #02293e;
--color-gold-dark: #715511;
--color-bg: light-dark(var(--color-blue-light), var(--color-blue-dark));
--color-text: light-dark(var(--color-blue-dark), var(--color-blue-light));
--color-accent: light-dark(var(--color-gold-dark), var(--color-gold-light));
} }
/* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */ /* numbered components are from https://www.joshwcomeau.com/css/custom-css-reset/ */
@@ -9,6 +18,7 @@
*:not(dialog) { *:not(dialog) {
margin: 0; /* 2. Remove default margin */ margin: 0; /* 2. Remove default margin */
padding: 0;
} }
@media (prefers-reduced-motion: no-preference) { @media (prefers-reduced-motion: no-preference) {
@@ -17,9 +27,31 @@
} }
} }
#root, #__next {
isolation: isolate; /* 10. Create a root stacking context */
}
body { body {
line-height: 1.5; /* 4. Increase line-height */ line-height: 1.5; /* 4. Increase line-height */
-webkit-font-smoothing: antialiased; /* 5. Improve text rendering */ -webkit-font-smoothing: antialiased; /* 5. Improve text rendering */
color: var(--color-text);
background-color: var(--color-bg);
font-family: "Atkinson Hyperlegible Next";
}
main {
width: 55%;
margin: 0 auto 2rem;
scroll-margin-top: 1.5rem;
min-height: 50vh;
padding-bottom: 2rem;
max-width: 1200px;
}
@media (max-width: 650px) {
main {
width: 92%;
}
} }
img, picture, video, canvas, svg { img, picture, video, canvas, svg {
@@ -38,12 +70,126 @@ p, h1, h2, h3, h4, h5, h6 {
p { p {
text-wrap: pretty; /* 9. Improve line wrapping */ text-wrap: pretty; /* 9. Improve line wrapping */
margin: 0 auto 1.5rem;
line-height: 1.5rem;
}
@media (max-width: 650px) {
p {
font-size: .9rem;
line-height: 1.3rem;
}
} }
h1, h2, h3, h4, h5, h6 { h1, h2, h3, h4, h5, h6 {
text-wrap: balance; /* 9. Improve line wrapping */ text-wrap: balance; /* 9. Improve line wrapping */
} }
#root, #__next { h1 {
isolation: isolate; /* 10. Create a root stacking context */ margin: 3rem auto 1rem;
text-align: center;
font-size: 2.2rem;
}
h2, h3 {
margin: 3rem auto .5rem;
color: var(--color-accent);
border-bottom: solid;
}
h2 {
font-size: 1.8rem;
}
h3 {
font-size: 1.35rem;
text-align: right;
}
@media (max-width: 650px) {
h1 {
font-size: 1.8rem;
}
h2 {
font-size: 1.5rem;
}
h3 {
font-size: 1.2rem;
}
}
a {
color: var(--color-text);
text-decoration: underline;
text-decoration-style: solid;
text-decoration-thickness: .2rem;
text-decoration-color: var(--color-accent);
transition: text-decoration-thickness .5s;
padding: 0 .15rem;
border-radius: .15rem;
}
@media (any-hover: hover) {
a:hover {
text-decoration-thickness: .4rem;
}
}
a:focus-visible {
text-decoration: none;
outline: var(--color-accent) solid .15rem;
}
ul {
margin: 0 auto 1.5rem 2rem;
line-height: 1.5rem;
}
@media (max-width: 650px) {
ul {
font-size: .9rem;
line-height: 1.3rem;
}
}
time {
font-weight: 700;
}
button {
cursor: pointer;
background-color: var(--color-bg);
}
header img {
max-height: 25vh;
max-width: 100%;
width: auto;
margin: 0 auto;
}
@media (max-width: 650px) {
header img {
max-height: 20vh;
}
}
@media (prefers-color-scheme: light) {
#logo-dark {
display: none;
}
}
@media (prefers-color-scheme: dark) {
#logo-light {
display: none;
}
}
#author {
text-align: right;
margin-bottom: 3rem;
font-style: italic;
} }
+119
View File
@@ -0,0 +1,119 @@
nav {
display: flex;
position: relative;
gap: 1rem;
justify-content: center;
margin: 1rem auto;
}
nav a,
nav button {
font-size: 1.4rem;
border: .1rem solid;
border-radius: .15rem;
padding: .15rem .3rem;
color: var(--color-accent);
text-decoration: none;
line-height: 2rem;
outline-offset: .1rem;
}
@media (max-width: 650px) {
nav a,
nav button {
font-size: 1.1rem;
}
}
@media (any-hover: hover) {
nav a:hover,
nav button:hover {
color: var(--color-bg);
background-color: var(--color-accent);
border-color: var(--color-accent);
}
}
nav a:focus-visible,
nav button:focus-visible {
outline: .1rem solid var(--color-accent);
}
#skip {
left: -999px;
position: absolute;
top: auto;
width: 1px;
height: 1px;
overflow: hidden;
z-index: -99;
background-color: var(--color-bg);
}
#skip:focus-visible {
left: 1rem;
width: auto;
height: auto;
overflow: auto;
z-index: 999;
}
@media (any-hover: hover) {
#skip:hover {
color: var(--color-bg);
background-color: var(--color-accent);
}
}
a[aria-current="page"] {
border-right-width: .5rem;
border-left-width: .5rem;
}
nav ul {
list-style: none;
display: none;
position: absolute;
z-index: 1;
margin: 0 0 0 1rem;
min-width: 10rem;
}
#dropdown {
position: relative;
display: inline-block;
min-width: 3rem;
}
nav ul.show {
display: block;
}
nav ul li {
margin: .5rem;
}
nav ul a {
display: inline-block;
background-color: var(--color-bg);
}
footer {
color: var(--color-bg);
background-color: var(--color-text);
padding: 1rem;
}
footer p {
text-align: center;
margin: 0;
}
footer a {
color: var(--color-bg);
text-decoration-color: var(--color-bg);
}
footer a:focus-visible {
outline-color: var(--color-bg);
}
+17
View File
@@ -1,5 +1,7 @@
import { attrs } from "@mdit/plugin-attrs"; import { attrs } from "@mdit/plugin-attrs";
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
import { markdownitLinkAttributes } from 'markdown-it-link-attributes';
import path from "node:path"; import path from "node:path";
import pluginFilters from "./_config/filters.js"; import pluginFilters from "./_config/filters.js";
@@ -8,6 +10,18 @@ export default async function (eleventyConfig) {
/* Markdown HTML attribute parsing */ /* Markdown HTML attribute parsing */
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(attrs)); eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(attrs));
/* Markdown apply target="_blank" to all external links */
const milaOptions = {
matcher(href) {
return href.match(/^https?:\/\//);
},
attrs: {
target: "_blank",
rel: "external",
},
};
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitLinkAttributes, milaOptions));
/* Bundles */ /* Bundles */
/* CSS */ /* CSS */
eleventyConfig.addBundle("css", { eleventyConfig.addBundle("css", {
@@ -49,6 +63,8 @@ export default async function (eleventyConfig) {
}, },
}); });
eleventyConfig.addPlugin(eleventyNavigationPlugin);
/* All filters from _config/filters.js */ /* All filters from _config/filters.js */
eleventyConfig.addPlugin(pluginFilters); eleventyConfig.addPlugin(pluginFilters);
@@ -59,6 +75,7 @@ export default async function (eleventyConfig) {
/* Watch when serving */ /* Watch when serving */
eleventyConfig.addWatchTarget("css"); eleventyConfig.addWatchTarget("css");
eleventyConfig.addWatchTarget("js");
} }
export const config = { export const config = {
Executable
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

+56
View File
@@ -0,0 +1,56 @@
const dropdown = document.getElementById("dropdown");
const dropdownButton = document.getElementById("drop-button");
const dropdownContent = document.getElementById("drop-content");
const dropdownItems = dropdownContent.querySelectorAll("a");
const firstDropdownItem = dropdownItems[0];
const lastDropdownItem = dropdownItems[dropdownItems.length - 1];
const openDropdown = function() {
dropdownContent.classList.add("show");
dropdownContent.ariaHidden = "false";
dropdownButton.ariaExpanded = "true";
}
const closeDropdown = function() {
if (dropdownButton.ariaExpanded === "true") {
dropdownContent.classList.remove("show");
dropdownContent.ariaHidden = "true";
dropdownButton.ariaExpanded = "false";
}
}
dropdownButton.addEventListener("click", (event) => {
if (dropdownButton.ariaExpanded === "false") openDropdown();
else closeDropdown();
});
dropdownButton.addEventListener("keydown", (event) => {
if (event.key === "Enter" || event.key === " ") { // Space or Enter key
event.preventDefault(); // Prevent the default action to stop scrolling when pressing Space
if (dropdownButton.ariaExpanded === "false") {
openDropdown();
} else {
closeDropdown();
}
} else if (event.key === "Tab" && event.shiftKey) closeDropdown();
});
firstDropdownItem.addEventListener("keydown", (event) => {
if (event.key === "Tab" && event.shiftKey) closeDropdown();
});
lastDropdownItem.addEventListener("keydown", (event) => {
if (event.key === "Tab" && !event.shiftKey) closeDropdown();
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape" && dropdownButton.ariaExpanded === "true") {
closeDropdown();
dropdownButton.focus();
}
});
window.addEventListener("click", (event) => {
if (!event.target.matches("#drop-button")) closeDropdown();
});
+79 -25
View File
@@ -1,17 +1,20 @@
{ {
"name": "11ty", "name": "siblinghood-11ty",
"version": "1.0.0", "version": "1.0.0",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "siblinghood-11ty",
"version": "1.0.0", "version": "1.0.0",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"devDependencies": { "devDependencies": {
"@11ty/eleventy": "^3.1.5", "@11ty/eleventy": "^3.1.5",
"@11ty/eleventy-img": "^6.0.4", "@11ty/eleventy-img": "^6.0.4",
"@11ty/eleventy-navigation": "^1.0.5",
"@mdit/plugin-attrs": "^0.25.1", "@mdit/plugin-attrs": "^0.25.1",
"luxon": "^3.7.2" "luxon": "^3.7.2",
"markdown-it-link-attributes": "https://github.com/lee0c/markdown-it-link-attributes/tarball/main"
} }
}, },
"node_modules/@11ty/dependency-tree": { "node_modules/@11ty/dependency-tree": {
@@ -165,6 +168,20 @@
"url": "https://opencollective.com/11ty" "url": "https://opencollective.com/11ty"
} }
}, },
"node_modules/@11ty/eleventy-navigation": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@11ty/eleventy-navigation/-/eleventy-navigation-1.0.5.tgz",
"integrity": "sha512-zb6xe29cM9viSdYtZywKIkJw2HIROyBINdBcFWC9uD0c/jYOTAex5nwy3HNEuh5t6/Ld/S9V4gEizfmeYuYpCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"dependency-graph": "^1.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/11ty"
}
},
"node_modules/@11ty/eleventy-plugin-bundle": { "node_modules/@11ty/eleventy-plugin-bundle": {
"version": "3.0.7", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz", "resolved": "https://registry.npmjs.org/@11ty/eleventy-plugin-bundle/-/eleventy-plugin-bundle-3.0.7.tgz",
@@ -919,9 +936,9 @@
} }
}, },
"node_modules/brace-expansion": { "node_modules/brace-expansion": {
"version": "1.1.14", "version": "1.1.21",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz",
"integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1441,9 +1458,9 @@
} }
}, },
"node_modules/gray-matter/node_modules/js-yaml": { "node_modules/gray-matter/node_modules/js-yaml": {
"version": "3.14.2", "version": "3.15.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.15.2.tgz",
"integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "integrity": "sha512-6EuL879VkRA+1Cz578mKMiKvjPNEuk6+r1JaFzoSWejZmtf7xWbIyw1e3KkxlkzTIt9Taw6JBhEppG7utc1P+w==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1659,10 +1676,20 @@
} }
}, },
"node_modules/js-yaml": { "node_modules/js-yaml": {
"version": "4.1.1", "version": "4.3.2",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==",
"dev": true, "dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/nodeca"
}
],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"argparse": "^2.0.1" "argparse": "^2.0.1"
@@ -1702,19 +1729,29 @@
} }
}, },
"node_modules/linkify-it": { "node_modules/linkify-it": {
"version": "5.0.0", "version": "5.0.2",
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.2.tgz",
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", "integrity": "sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==",
"dev": true, "dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"uc.micro": "^2.0.0" "uc.micro": "^2.0.0"
} }
}, },
"node_modules/liquidjs": { "node_modules/liquidjs": {
"version": "10.25.7", "version": "10.29.0",
"resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.25.7.tgz", "resolved": "https://registry.npmjs.org/liquidjs/-/liquidjs-10.29.0.tgz",
"integrity": "sha512-rPCjJLiD4eDhQjvv964AeXFC+HbeYBbZrd7Z82Q6hqv1lX7G+5w4SJcKLn9CAAAwHI4aS3dTdo083UB79K3pDA==", "integrity": "sha512-pCVOhs6FLAR8su3ItJ07diN26t6W5dHQRnmTMy8HPyTFuv1+oSCVJIGp5pGjfQyOZfh50KswvKtMTp6p4JEIdw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@@ -1750,15 +1787,25 @@
} }
}, },
"node_modules/markdown-it": { "node_modules/markdown-it": {
"version": "14.1.1", "version": "14.3.2",
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.3.2.tgz",
"integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==", "integrity": "sha512-sHHjZ5fJKlgrG4qns2YwVcdNep35h5fERrfkD2YNsb9UFk0UIHarbiTaHKVMlPuWAoiilyK8Fv/jAm11slsY7Q==",
"dev": true, "dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/puzrin"
},
{
"type": "github",
"url": "https://github.com/sponsors/markdown-it"
}
],
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"argparse": "^2.0.1", "argparse": "^2.0.1",
"entities": "^4.4.0", "entities": "^4.5.0",
"linkify-it": "^5.0.0", "linkify-it": "^5.0.2",
"mdurl": "^2.0.0", "mdurl": "^2.0.0",
"punycode.js": "^2.3.1", "punycode.js": "^2.3.1",
"uc.micro": "^2.1.0" "uc.micro": "^2.1.0"
@@ -1767,6 +1814,13 @@
"markdown-it": "bin/markdown-it.mjs" "markdown-it": "bin/markdown-it.mjs"
} }
}, },
"node_modules/markdown-it-link-attributes": {
"version": "4.0.1",
"resolved": "https://github.com/lee0c/markdown-it-link-attributes/tarball/main",
"integrity": "sha512-AWUn7JiBi431HkZyXR2MRJxU0wQolHmG/TFCrRSq+w/q4mIzY7c3QKBF1eYEQwXx8IKLdmBVxZA37tp3S1ZkYQ==",
"dev": true,
"license": "MIT"
},
"node_modules/markdown-it/node_modules/entities": { "node_modules/markdown-it/node_modules/entities": {
"version": "4.5.0", "version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -2399,9 +2453,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/ws": { "node_modules/ws": {
"version": "8.20.1", "version": "8.21.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.20.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.3.tgz",
"integrity": "sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==", "integrity": "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
+4 -2
View File
@@ -4,7 +4,7 @@
"description": "", "description": "",
"scripts": { "scripts": {
"build": "rm -rf _site && npx @11ty/eleventy --quiet", "build": "rm -rf _site && npx @11ty/eleventy --quiet",
"dev": "rm -rf _live && npx @11ty/eleventy --serve --quiet --output _live" "dev": "rm -rf _site && npx @11ty/eleventy --serve --quiet --output _site"
}, },
"author": "Lee Cattarin", "author": "Lee Cattarin",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
@@ -12,7 +12,9 @@
"devDependencies": { "devDependencies": {
"@11ty/eleventy": "^3.1.5", "@11ty/eleventy": "^3.1.5",
"@11ty/eleventy-img": "^6.0.4", "@11ty/eleventy-img": "^6.0.4",
"@11ty/eleventy-navigation": "^1.0.5",
"@mdit/plugin-attrs": "^0.25.1", "@mdit/plugin-attrs": "^0.25.1",
"luxon": "^3.7.2" "luxon": "^3.7.2",
"markdown-it-link-attributes": "https://github.com/lee0c/markdown-it-link-attributes/tarball/main"
} }
} }
+9
View File
@@ -0,0 +1,9 @@
---
title: attribution
---
# Attribution
This website is built with [{{ eleventy.generator }}](https://www.11ty.dev/) and hosted by [heckin' technology](https://heckin.technology/). It's been hand-coded from the ground up [without the use of generative AI](https://declare-ai.org/1.0.0/none.html).
The font is [Atkinson Hyperlegible Next](https://brailleinstitute.org/freefont), specifically designed for low-vision readers to improve character recognition.
+23
View File
@@ -0,0 +1,23 @@
---
title: card one's travels
eleventyNavigation:
key: card one
order: 1
---
<h1>The Travels of <span class="card">Card One</span></h1>
<p><span class="card">Card one</span> has 16 total recipients. Its journey began in late December, 2025.</p>
{% set stops = collections["1a"] %}
{% include "card.njk" %}
<p>
Unfortunately, <span class="card">card one</span> stopped here at a recipient with ill health. Finally, I made the executive
decision to start a fresh card and send it on to the next recipient. Thanks to some miscommunication,
the person <em>after</em> me also started a new card - so we went with that one as the official one,
and I was skipped. Woops!
</p>
{% set stops = collections["1b"] %}
{% include "card.njk" %}
+13
View File
@@ -0,0 +1,13 @@
---
title: card three's travels
eleventyNavigation:
key: card three
order: 1
---
<h1>The Travels of <span class="card">Card Three</span></h1>
<p><span class="card">Card three</span> has 16 total recipients. Its journey began in late July, 2026.</p>
{% set stops = collections["3"] %}
{% include "card.njk" %}
+13
View File
@@ -0,0 +1,13 @@
---
title: card two's travels
eleventyNavigation:
key: card two
order: 1
---
<h1>The Travels of <span class="card">Card Two</span></h1>
<p><span class="card">Card two</span> has 16 total recipients. Its journey began in early January, 2026.</p>
{% set stops = collections["2"] %}
{% include "card.njk" %}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 999 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 609 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 233 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 331 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

+94
View File
@@ -0,0 +1,94 @@
---
title: siblinghood of the traveling greeting card
---
# Siblinghood of the Traveling Greeting Card
a community-building project by [lee](https://leecat.art).{id="author"}
welcome to the siblinghood of the traveling greeting card.
[originated on the fediverse](https://flipping.rocks/@inherentlee/115645750535211187) with an idea from [noctiluca@scholar.social](https://scholar.social/@noctiluca).
## objective
send a greeting card around the world. Maybe more than one. We'll see.
## outline
from a group of participants, a random list will be formed. every person is given the address of the next person in the list (the last person receives the first person's address). First person picks a greeting card, signs it, and sends it to their designated recipient; that person receives, signs, sends on, etc.
this continues on to the last person, who finally signs and sends back to the first, closing the loop and ending the adventure. The first person gets to keep the card they originally sent out.
if we want to, this can be easily re-run - add folks who want to be added, drop folks who want to be dropped, scramble the list, and start again.
### timeline
applications for round one (cards one and two) closed on <time datetime="2025-12-15">December 15th, 2025</time>. Round two (card three) closed on <time datetime="2026-05-01">May 1st, 2026</time>. You may still put in for future rounds, but be aware future rounds are not confirmed yet and will not be confirmed for at least 6 months.
assignments (recipient address, order in loop) for cards one and two have been sent out as of <time datetime="2025-12-26">December 26th, 2025</time>. Assignments for card three have been sent out as of <time datetime="2026-06-04">June 4th, 2026</time>.
### participants
each cohort will be 16 people. When signups for the next round hit 16, I will confirm with all folks that they are still in; if so, we'll kick it off (if not, we'll wait for another person or two).
for the round that began <time datetime="2026-01-01">January of 2026</time>, we have 32 participants and will have two cards in circulation. All following rounds will kick off when 16 signups have been reached.
### on randomization
I will edit the list as needed to accommodate any mailing restrictions. I will also re-roll if I am placed first on the list.
### card guidelines
4x6 inches/10x15 centimeters minimum size recommended so there is space for everyone to sign. Must not require an unusual envelope e.g. square or similar. Must meet letter rates so nothing too heavy.
### address privacy
the only people who will see your address are:
- me
- the person who is sending directly to you
- if you put a return address (which I really would recommend), your recipient
## what I'll need from participants
### signing the card
sign in any way you find meaningful. Please don't hog the card space - remember that as many as ~2 dozen people will be signing it!
**IMPORTANT!** Only put a name, nickname, doodle, fedi handle, etc. on the card that you are comfortable having displayed publicly. In any posts that I make, it will not be directly connected to you. However, as there are only 16 signers per card, please be aware that how you sign could be tied back to your fedi account.
### mailing the card
this will require a fresh envelope and stamp(s) as needed for postage.
### status checks
this is, at the end of the day, pretty flexible, but what I would really, really like is:
- 2 emails, one on receipt and one on re-sending. This allows me to check in on progress and ensure the card doesn't get too stalled, or lost.
- more optionally, but fun for seeing how things are going: a picture of the card (not the envelope!)
feel free to post your card pictures using the hashtags #siblinghoodOfTheTravelingGreetingCard or #sottgc.
## what I'll send participants
### guidelines
summary/highlights of these guidelines will be repeated over email. Full guidelines will always be available here.
### recipient and loop order assignment
each participant will be sent the name and address of the next person in the loop. They will also be sent their place in the loop, **numbered from 0**.
### reminders
I'll be doing my level best to track the card's movement, so as it is sent around (assuming I get check-ins from y'all! please help me out here!). I will send out reminders to folks to either check their mail or make sure the card gets sent out again. Some folks have specifically asked for this support and I don't want to let them down, so more communication is always better.
## I want in!
as stated above, signups for the rounds beginning <time datetime="2026-01-01">January 1st, 2026</time> and <time datetime="2026-06-04">June 4th, 2026</time> are closed. However, you may still sign up in case of future rounds.
[sign up for the siblinghood of the traveling greeting card](https://airtable.com/appdoHZsRDUzgYu9q/pagsr9LVAqKx29gDl/form).
if airtable is in any way inaccessible to you, please [reach out directly to lee](https://leecat.art/contact).
+1 -1
View File
@@ -1,3 +1,3 @@
export default { export default {
layout: "page.njk", layout: "base.njk",
}; };
+5
View File
@@ -0,0 +1,5 @@
export default {
tags: [
"1a"
]
};
+6
View File
@@ -0,0 +1,6 @@
---
location: California, USA
img:
src: one/00.jpg
alt: an open pop-up greeting card. the pop-up is an autumnal tree, and the inside of the card has autumn leaf designs. two small figurines sit on the card to hold it open flat.
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Italy
img:
src: one/01.jpg
alt: an open pop-up greeting card viewed from the top. there's what appears to be a black butterfly or moth sticker/cutout in it. next to it is a note that someone has signed.
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Oregon, USA
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Alberta, Canada
img:
src: one/03.jpg
alt: an open pop-up greeting card on a table, weighted down with a tiny ceramic cat. behind it is a vase, a potted plant, and a bird statuette.
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Belgium
---
+5
View File
@@ -0,0 +1,5 @@
export default {
tags: [
"1b"
]
};
+3
View File
@@ -0,0 +1,3 @@
---
location: United Kingdom
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Florida, USA
img:
src: one/07.jpg
alt: the front of a card with a design of flowers, probably lilies, on top of a mostly hidden envelope.
---
+3
View File
@@ -0,0 +1,3 @@
---
location: New York, USA
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Illinois, USA
img:
src: one/09.jpg
alt: the inside of a greeting card with several signatures. One signature wraps around a 'no pride in genocide' sticker showing crossed Palestine and trans flags. One wraps around a sticker of a raccoon throwing its hands up and looking goofy.
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Pennsylvania, USA
img:
src: one/10.jpg
alt: Part of the inside of a greeting card as well as a postcard or sticker of a flower and part of a sheet of dino stickers. The greeting card has a dino sticker inside with a signature wrapped around it.
---
+5
View File
@@ -0,0 +1,5 @@
export default {
tags: [
"2"
]
};
+6
View File
@@ -0,0 +1,6 @@
---
location: Oregon, USA
img:
src: two/00.jpg
alt: "an open greeting card, blank except for some small writing that reads 'Hello from Oregon, USA! -freddie (#0)"
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Sweden
img:
src: two/01.jpg
alt: "a close crop of the front of a card, indicating maybe a picture of a cat and a question mark."
---
+3
View File
@@ -0,0 +1,3 @@
---
location: France
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Netherlands
img:
src: two/03.jpg
alt: "the inside of the card with several signatures: freddie, herzleid, laen, and flann"
---
+3
View File
@@ -0,0 +1,3 @@
---
location: New Zealand
---
+3
View File
@@ -0,0 +1,3 @@
---
location: United Kingdom
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Nova Scotia, Canada
img:
src: two/06.jpg
alt: "a piece of paper that says in all caps, sticker trove, with a mostly hidden pile of stickers underneath"
---
+3
View File
@@ -0,0 +1,3 @@
---
location: United Kingdom
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Italy
img:
src: two/08.jpg
alt: "an open greeting card amidst a pile of colorful stickers. It is signed by 8 different people."
---
+3
View File
@@ -0,0 +1,3 @@
---
location: United Kingdom
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Minnesota, USA
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Connecticut, USA
img:
src: two/11.jpg
alt: the inside of a card signed by eleven people
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Oregon, USA
---
+3
View File
@@ -0,0 +1,3 @@
---
location: British Columbia, Canada
---
+6
View File
@@ -0,0 +1,6 @@
---
location: Oregon, USA
img:
src: two/14.jpg
alt: "the inside of a card signed by fifteen people, including a bundle that reads 'sticker trove!' and a small piece of paper that says 'be happy.'"
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Illinois, USA
---
+3
View File
@@ -0,0 +1,3 @@
---
location: Lousiana, USA
---
+5
View File
@@ -0,0 +1,5 @@
export default {
tags: [
"3"
]
};
+3
View File
@@ -0,0 +1,3 @@
export default {
permalink: false
};
+6
View File
@@ -0,0 +1,6 @@
---
location:
img:
src:
alt:
---