all but posts omg
This commit is contained in:
@ -1,10 +1,9 @@
|
|||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
|
|
||||||
export default function(eleventyConfig) {
|
export default function(eleventyConfig) {
|
||||||
/* Human-readable dates */
|
// Return the keys used in an object
|
||||||
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
|
eleventyConfig.addFilter("getKeys", target => {
|
||||||
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" })
|
return Object.keys(target);
|
||||||
.toLocaleString(DateTime.DATE_FULL);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* For <time> elements */
|
/* For <time> elements */
|
||||||
@ -12,8 +11,20 @@ export default function(eleventyConfig) {
|
|||||||
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
|
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Human-readable dates */
|
||||||
|
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
|
||||||
|
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" })
|
||||||
|
.toLocaleString(DateTime.DATE_FULL);
|
||||||
|
});
|
||||||
|
|
||||||
/* Filter out structural tags */
|
/* Filter out structural tags */
|
||||||
eleventyConfig.addFilter("removeBasicTags", (tags) => {
|
eleventyConfig.addFilter("removeBasicTags", (tags) => {
|
||||||
return tags.filter(tag => ["all", "posts", "gallery", "reference", "tagPagination"].indexOf(tag) === -1);
|
return tags.filter(tag => ["all", "posts", "gallery", "reference", "tagPagination"].indexOf(tag) === -1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* What it says */
|
||||||
|
eleventyConfig.addFilter("sortAlphabetically", strings =>
|
||||||
|
(strings || []).sort((b, a) => b.localeCompare(a))
|
||||||
|
);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -23,26 +23,24 @@
|
|||||||
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
{# Styles #}
|
{# Styles #}
|
||||||
<link rel="stylesheet" href="/assets/css/main.css">
|
<style>{% include "css/main.css" %}</style>
|
||||||
<link rel="stylesheet" href="/assets/css/nav.css">
|
<style>{% include "css/nav.css" %}</style>
|
||||||
<link rel="stylesheet" href="/assets/css/highlighting.css">
|
<style>{% include "css/print.css" %}</style>
|
||||||
<link rel="stylesheet" href="/assets/css/print.css">
|
|
||||||
<link rel="stylesheet" href="/assets/css/postlist.css">
|
|
||||||
<link rel="stylesheet" href="/assets/css/post.css">
|
|
||||||
|
|
||||||
{# Heading anchors #}
|
<style>{% getBundle "css" %}</style>
|
||||||
<script type="module">{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}</script>
|
|
||||||
|
<script type="module">{% getBundle "js" %}</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{% include "header.njk" %}
|
{% include "header.njk" %}
|
||||||
|
|
||||||
<main id="main">
|
<main id="main">
|
||||||
<heading-anchors>
|
{{ content | safe }}
|
||||||
{{ content | safe }}
|
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
</heading-anchors>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
{% include "footer.njk" %}
|
{% include "footer.njk" %}
|
||||||
|
|
||||||
|
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
8
_includes/layouts/page-lists.njk
Normal file
8
_includes/layouts/page-lists.njk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
layout: base.njk
|
||||||
|
---
|
||||||
|
{% css %}{% include "css/lists.css" %}{% endcss %}
|
||||||
|
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
{{ content | safe }}
|
||||||
@ -1,6 +1,10 @@
|
|||||||
---
|
---
|
||||||
layout: base.njk
|
layout: base.njk
|
||||||
---
|
---
|
||||||
<h1>{{ title }}</h1>
|
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||||
|
|
||||||
{{ content | safe }}
|
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
||||||
|
<h1>{{ title }}</h1>
|
||||||
|
|
||||||
|
{{ content | safe }}
|
||||||
|
</heading-anchors>
|
||||||
|
|||||||
@ -1,31 +1,37 @@
|
|||||||
---
|
---
|
||||||
layout: base.njk
|
layout: base.njk
|
||||||
---
|
---
|
||||||
<article>
|
{% css %}{% include "css/post.css" %}{% endcss %}
|
||||||
<h1>{{ title }}</h1>
|
{% css %}{% include "css/highlighting.css" %}{% endcss %}
|
||||||
|
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
|
||||||
|
|
||||||
<div class="post-metadata">
|
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
|
||||||
<p>
|
<article>
|
||||||
posted on
|
<h1>{{ title }}</h1>
|
||||||
<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time>
|
|
||||||
by {{ metadata.author }}
|
<div class="post-metadata">
|
||||||
</p>
|
<p>
|
||||||
{% set relevantTags = tags | removeBasicTags %}
|
posted on
|
||||||
{% if relevantTags.length %}
|
<time datetime="{{ page.date | htmlDateString }}">{{ page.date | readableDate }}</time>
|
||||||
<ul class="post-tags">
|
by {{ metadata.author }}
|
||||||
{% for tag in relevantTags %}
|
</p>
|
||||||
<li>
|
{% set relevantTags = tags | removeBasicTags %}
|
||||||
{% set tagUrl %}/tag/{{ tag | slugify }}/{% endset %}
|
{% if relevantTags.length %}
|
||||||
<a href="{{ tagUrl }}">{{ tag }}</a>
|
<ul class="post-tags">
|
||||||
</li>
|
{% for tag in relevantTags %}
|
||||||
{% endfor %}
|
<li>
|
||||||
</ul>
|
{% set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
|
||||||
|
<a href="{{ tagUrl }}">{{ tag }}</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if image %}
|
||||||
|
<img src="/img/{{ image.src }}" alt="{{ image.alt }}">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
|
||||||
|
|
||||||
{% if image %}
|
{{ content | safe }}
|
||||||
<img src="/img/{{ image.src }}" alt="{{ image.alt }}">
|
</article>
|
||||||
{% endif %}
|
</heading-anchors>
|
||||||
|
|
||||||
{{ content | safe }}
|
|
||||||
</article>
|
|
||||||
|
|||||||
6
_includes/layouts/resume.njk
Normal file
6
_includes/layouts/resume.njk
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
layout: base.njk
|
||||||
|
---
|
||||||
|
{% css %}{% include "css/resume.css" %}{% endcss %}
|
||||||
|
|
||||||
|
{{ content | safe }}
|
||||||
@ -4,14 +4,14 @@
|
|||||||
{% if olderHref %}
|
{% if olderHref %}
|
||||||
<li class="older">
|
<li class="older">
|
||||||
<a href="{{ olderHref }}">
|
<a href="{{ olderHref }}">
|
||||||
<i class="fa-solid fa-hand-point-left"></i> older
|
<i class="fa-solid fa-hand-point-left" aria-hidden="true"></i> older
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if newerHref %}
|
{% if newerHref %}
|
||||||
<li class="newer">
|
<li class="newer">
|
||||||
<a href="{{ newerHref }}">
|
<a href="{{ newerHref }}">
|
||||||
newer <i class="fa-solid fa-hand-point-right"></i>
|
newer <i class="fa-solid fa-hand-point-right" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
25
_includes/webring.njk
Normal file
25
_includes/webring.njk
Normal file
@ -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>
|
||||||
@ -1,28 +1,31 @@
|
|||||||
#postlist {
|
#postlist,
|
||||||
|
#taglist {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#postlist, .post,
|
||||||
|
#taglist, .tag {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post {
|
/* Odd-numbered posts & tag layout/coloration */
|
||||||
margin: 0;
|
.post:nth-child(odd) .postlink,
|
||||||
}
|
.tag:nth-child(odd) .taglink {
|
||||||
|
|
||||||
/* Odd-numbered post layout/coloration */
|
|
||||||
.post:nth-child(odd) .postlink {
|
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
'img h2'
|
'img h2'
|
||||||
'img tags'
|
'img info'
|
||||||
'img .';
|
'img .';
|
||||||
grid-template-columns: 45% auto;
|
grid-template-columns: 45% auto;;
|
||||||
--color-primary: var(--color-teal);
|
--color-primary: var(--color-teal);
|
||||||
--color-accent: var(--color-pink);
|
--color-accent: var(--color-pink);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Even-numbered post layout/coloration */
|
/* Even-numbered posts & tags layout/coloration */
|
||||||
.post:nth-child(even) .postlink {
|
.post:nth-child(even) .postlink,
|
||||||
|
.tag:nth-child(even) .taglink {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
'h2 img'
|
'h2 img'
|
||||||
'tags img'
|
'info img'
|
||||||
'. img';
|
'. img';
|
||||||
grid-template-columns: auto 45%;
|
grid-template-columns: auto 45%;
|
||||||
--color-primary: var(--color-pink);
|
--color-primary: var(--color-pink);
|
||||||
@ -31,24 +34,25 @@
|
|||||||
|
|
||||||
/* Layout for all posts on mobile */
|
/* Layout for all posts on mobile */
|
||||||
@media (max-width: 650px) {
|
@media (max-width: 650px) {
|
||||||
.post:nth-child(n) .postlink {
|
.post:nth-child(n) .postlink,
|
||||||
|
.tag:nth-child(n) .taglink {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
'img'
|
'img'
|
||||||
'h2'
|
'h2'
|
||||||
'tags';
|
'info';
|
||||||
grid-template-columns: auto;
|
grid-template-columns: auto;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link */
|
/* Link */
|
||||||
.postlink {
|
.postlink,
|
||||||
|
.taglink {
|
||||||
display: grid;
|
display: grid;
|
||||||
border: .25rem solid;
|
border: .25rem solid var(--color-primary);
|
||||||
border-radius: 1.25rem;
|
border-radius: 1.25rem;
|
||||||
box-shadow: .35rem .35rem var(--color-shadow);
|
box-shadow: .35rem .35rem var(--color-shadow);
|
||||||
margin: 2rem 0;
|
margin: 2rem 0;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
border-color: var(--color-primary);
|
|
||||||
/* Click animation handling */
|
/* Click animation handling */
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 0;
|
top: 0;
|
||||||
@ -56,26 +60,30 @@
|
|||||||
transition: top .05s ease-in, left .05s ease-in;
|
transition: top .05s ease-in, left .05s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.postlink:focus-visible {
|
.postlink:focus-visible,
|
||||||
|
.taglink:focus-visible {
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
.postlink:hover {
|
.postlink:hover,
|
||||||
|
.taglink:hover {
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Forced colors */
|
/* Forced colors */
|
||||||
@media (forced-colors: active) {
|
@media (forced-colors: active) {
|
||||||
.postlink:focus-visible {
|
.postlink:focus-visible,
|
||||||
|
.taglink:focus-visible {
|
||||||
outline-offset: .25rem;
|
outline-offset: .25rem;
|
||||||
outline: .25rem solid;
|
outline: .25rem solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
.postlink:hover {
|
.postlink:hover,
|
||||||
|
.taglink:hover {
|
||||||
outline-offset: .25rem;
|
outline-offset: .25rem;
|
||||||
outline: .25rem solid;
|
outline: .25rem solid;
|
||||||
}
|
}
|
||||||
@ -83,23 +91,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Click animation */
|
/* Click animation */
|
||||||
.postlink:active {
|
.postlink:active,
|
||||||
|
.taglink:active {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
top: .2rem;
|
top: .2rem;
|
||||||
left: .2rem;
|
left: .2rem;
|
||||||
box-shadow: .15rem .15rem var(--color-shadow);
|
box-shadow: .15rem .15rem var(--color-shadow);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Post elements */
|
/* Post & tag elements */
|
||||||
.post h2,
|
.post h2, .post img,
|
||||||
.post img,
|
.post ul, .post li,
|
||||||
.post ul,
|
.tag h2, .tag p,
|
||||||
.post li {
|
.tag img {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Headers */
|
.post h2,
|
||||||
.post h2 {
|
.tag h2 {
|
||||||
grid-area: h2;
|
grid-area: h2;
|
||||||
padding: .25rem .5rem;
|
padding: .25rem .5rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
@ -109,30 +118,62 @@
|
|||||||
border-bottom: .25rem solid var(--color-accent);
|
border-bottom: .25rem solid var(--color-accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
.post:nth-child(even) h2 {
|
.post:nth-child(even) h2,
|
||||||
|
.tag:nth-child(even) h2 {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.postlink:focus-visible h2 {
|
.postlink:focus-visible h2,
|
||||||
|
.taglink:focus-visible h2 {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
border-color: var(--color-bg);
|
border-color: var(--color-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
.postlink:hover h2 {
|
.postlink:hover h2,
|
||||||
|
.taglink:hover h2 {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
border-color: var(--color-bg);
|
border-color: var(--color-bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Image */
|
/* Images */
|
||||||
.post img {
|
.post img,
|
||||||
|
.tag-imgs {
|
||||||
grid-area: img;
|
grid-area: img;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Tags */
|
.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: calc(1rem);
|
||||||
|
}
|
||||||
|
|
||||||
|
.taglink:focus-visible .missing-image {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (any-hover: hover) {
|
||||||
|
.taglink:hover .missing-image {
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Post tags */
|
||||||
.postlist-tags {
|
.postlist-tags {
|
||||||
grid-area: tags;
|
grid-area: info;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: row wrap;
|
flex-flow: row wrap;
|
||||||
@ -144,25 +185,35 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
|
|
||||||
.post:nth-child(odd) .postlist-tags {
|
.postlist-tags li,
|
||||||
justify-content: flex-start;
|
.tagcount {
|
||||||
}
|
|
||||||
|
|
||||||
.postlist-tags li {
|
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
padding: 0 .5rem;
|
padding: 0 .5rem;
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.postlink:focus-visible .postlist-tags li {
|
.postlink:focus-visible .postlist-tags li,
|
||||||
|
.taglink:focus-visible .tagcount {
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
.postlink:hover .postlist-tags li {
|
.postlink:hover .postlist-tags li,
|
||||||
|
.taglink:hover .tagcount {
|
||||||
background-color: var(--color-bg);
|
background-color: var(--color-bg);
|
||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tag count */
|
||||||
|
.tag p {
|
||||||
|
grid-area: info;
|
||||||
|
padding: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag:nth-child(odd) p {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
43
css/main.css
43
css/main.css
@ -96,15 +96,19 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
h1 {
|
h1 {
|
||||||
margin-top: 3rem;
|
margin-top: 3rem;
|
||||||
font-size: 3.5rem;
|
font-size: 3.5rem;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
margin-top: 1rem;
|
margin-top: 2rem;
|
||||||
font-size: 2.2rem;
|
font-size: 2.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin-top: 1.5rem;
|
margin-top: 1.5rem;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4, h5, h6 {
|
h4, h5, h6 {
|
||||||
margin-top: 1rem;
|
margin-top: 1rem;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
@ -131,7 +135,7 @@ b {
|
|||||||
|
|
||||||
/* Links */
|
/* Links */
|
||||||
a {
|
a {
|
||||||
color: var(--color-font);
|
color: var(--color-text);
|
||||||
border-radius: .25rem;
|
border-radius: .25rem;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
text-decoration-style: solid;
|
text-decoration-style: solid;
|
||||||
@ -155,23 +159,45 @@ a:active {
|
|||||||
text-decoration-thickness: .4em;
|
text-decoration-thickness: .4em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Heading anchors */
|
||||||
|
a.ha,
|
||||||
|
span.ha-placeholder {
|
||||||
|
color: var(--color-pink);
|
||||||
|
}
|
||||||
|
span.ha-placeholder {
|
||||||
|
opacity: .55;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Lists */
|
/* Lists */
|
||||||
::marker {
|
::marker {
|
||||||
color: var(--color-pink);
|
color: var(--color-pink);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul, ol, li {
|
ul, ol, dl, li {
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
line-height: 1.5;
|
line-height: 1.2 5;
|
||||||
|
margin-top: .65rem;
|
||||||
|
margin-bottom: .65rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
li ul, li ol {
|
li ul, li ol {
|
||||||
margin: .5rem 0;
|
margin: .5rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dt {
|
||||||
|
font-weight: 900;
|
||||||
|
margin-top: .5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
dd {
|
||||||
|
margin-left: 2rem;
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Blockquotes */
|
/* Blockquotes */
|
||||||
blockquote {
|
blockquote {
|
||||||
margin: .5rem 1rem;
|
margin: .5rem 1rem;
|
||||||
@ -232,3 +258,12 @@ hr:last-child {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Used on home, reference, gallery pages */
|
||||||
|
.centered {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Currently only used for resume, but it's generalizable */
|
||||||
|
.upper {
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
|||||||
64
css/nav.css
64
css/nav.css
@ -10,7 +10,8 @@ header {
|
|||||||
|
|
||||||
/* Header links, pagination links */
|
/* Header links, pagination links */
|
||||||
header a,
|
header a,
|
||||||
.pagination a {
|
.pagination a,
|
||||||
|
.webring ul a {
|
||||||
border-radius: 1rem;
|
border-radius: 1rem;
|
||||||
border: .125rem solid var(--color-pink);
|
border: .125rem solid var(--color-pink);
|
||||||
color: var(--color-pink);
|
color: var(--color-pink);
|
||||||
@ -26,16 +27,21 @@ header a,
|
|||||||
}
|
}
|
||||||
|
|
||||||
header a,
|
header a,
|
||||||
.pagination .older a {
|
.pagination .older a,
|
||||||
|
.webring .prev a,
|
||||||
|
.webring .rand a {
|
||||||
padding-right: .35rem;
|
padding-right: .35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination .newer a {
|
.pagination .newer a,
|
||||||
|
.webring .next a,
|
||||||
|
.webring .rand a {
|
||||||
padding-left: .35rem;
|
padding-left: .35rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
header a:focus-visible,
|
header a:focus-visible,
|
||||||
.pagination a:focus-visible {
|
.pagination a:focus-visible,
|
||||||
|
.webring ul a:focus-visible {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
border-color: var(--color-pink);
|
border-color: var(--color-pink);
|
||||||
background-color: var(--color-pink);
|
background-color: var(--color-pink);
|
||||||
@ -44,7 +50,8 @@ header a:focus-visible,
|
|||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
header a:hover,
|
header a:hover,
|
||||||
.pagination a:hover {
|
.pagination a:hover,
|
||||||
|
.webring ul a:hover {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
border-color: var(--color-pink);
|
border-color: var(--color-pink);
|
||||||
background-color: var(--color-pink);
|
background-color: var(--color-pink);
|
||||||
@ -53,14 +60,16 @@ header a:focus-visible,
|
|||||||
|
|
||||||
@media (forced-colors: active) {
|
@media (forced-colors: active) {
|
||||||
header a:focus-visible,
|
header a:focus-visible,
|
||||||
.pagination a:focus-visible {
|
.pagination a:focus-visible,
|
||||||
|
.webring ul a:focus-visible {
|
||||||
outline-offset: .125rem;
|
outline-offset: .125rem;
|
||||||
outline: .125rem solid;
|
outline: .125rem solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
header a:hover,
|
header a:hover,
|
||||||
.pagination a:hover {
|
.pagination a:hover,
|
||||||
|
.webring ul a:hover {
|
||||||
outline-offset: .125rem;
|
outline-offset: .125rem;
|
||||||
outline: .125rem solid;
|
outline: .125rem solid;
|
||||||
}
|
}
|
||||||
@ -69,7 +78,8 @@ header a:focus-visible,
|
|||||||
|
|
||||||
/* Click animation */
|
/* Click animation */
|
||||||
header a:active,
|
header a:active,
|
||||||
.pagination a:active {
|
.pagination a:active,
|
||||||
|
.webring ul a:active {
|
||||||
top: .1rem;
|
top: .1rem;
|
||||||
left: .1rem;
|
left: .1rem;
|
||||||
box-shadow: .05rem .05rem var(--color-shadow);
|
box-shadow: .05rem .05rem var(--color-shadow);
|
||||||
@ -97,28 +107,40 @@ header a[aria-current="page"]:focus-visible {
|
|||||||
|
|
||||||
/* Header link icons, pagination icons */
|
/* Header link icons, pagination icons */
|
||||||
header i,
|
header i,
|
||||||
.pagination i {
|
.pagination i,
|
||||||
|
.webring ul i {
|
||||||
color: var(--color-teal);
|
color: var(--color-teal);
|
||||||
}
|
}
|
||||||
|
|
||||||
header i {
|
header i,
|
||||||
|
.pagination .older i,
|
||||||
|
.webring .prev i,
|
||||||
|
.webring .rand i:nth-child(1) {
|
||||||
padding-left: .25rem;
|
padding-left: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.pagination .newer i,
|
||||||
|
.webring .next i,
|
||||||
|
.webring .rand i:nth-child(2) {
|
||||||
|
padding-right: .25rem;
|
||||||
|
}
|
||||||
|
|
||||||
header a[aria-current="page"] i {
|
header a[aria-current="page"] i {
|
||||||
color: var(--color-pink);
|
color: var(--color-pink);
|
||||||
}
|
}
|
||||||
|
|
||||||
header a:focus-visible i,
|
header a:focus-visible i,
|
||||||
a[aria-current="page"] a:focus-visible i,
|
a[aria-current="page"] a:focus-visible i,
|
||||||
.pagination a:focus-visible :in-range {
|
.pagination a:focus-visible i,
|
||||||
|
.webring ul a:focus-visible i {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (any-hover: hover) {
|
@media (any-hover: hover) {
|
||||||
header a:hover i,
|
header a:hover i,
|
||||||
header a[aria-current="page"]:hover i,
|
header a[aria-current="page"]:hover i,
|
||||||
.pagination a:hover i {
|
.pagination a:hover i,
|
||||||
|
.webring ul a:hover i {
|
||||||
color: var(--color-bg);
|
color: var(--color-bg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,3 +258,21 @@ footer a:focus-visible {
|
|||||||
grid-area: newer;
|
grid-area: newer;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* webring navigation */
|
||||||
|
.webring {
|
||||||
|
margin-bottom: 3rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webring ul {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
list-style: none;
|
||||||
|
justify-content: space-around;
|
||||||
|
gap: .35rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.webring ul,
|
||||||
|
.webring li {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|||||||
32
css/palette.css
Normal file
32
css/palette.css
Normal file
@ -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); }
|
||||||
41
css/resume.css
Normal file
41
css/resume.css
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.job p {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
@ -1,3 +1,4 @@
|
|||||||
|
import { IdAttributePlugin } from "@11ty/eleventy";
|
||||||
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
|
||||||
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
|
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
|
||||||
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
|
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
|
||||||
@ -11,6 +12,19 @@ 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));
|
||||||
|
|
||||||
|
/* Bundles */
|
||||||
|
/* CSS */
|
||||||
|
eleventyConfig.addBundle("css", {
|
||||||
|
toFileDirectory: "dist",
|
||||||
|
bundleHtmlContentFromSelector: "style",
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Javascript */
|
||||||
|
eleventyConfig.addBundle("js", {
|
||||||
|
toFileDirectory: "dist",
|
||||||
|
bundleHtmlContentFromSelector: "script",
|
||||||
|
});
|
||||||
|
|
||||||
/* Collections */
|
/* Collections */
|
||||||
/* Tag pagination */
|
/* Tag pagination */
|
||||||
eleventyConfig.addCollection("tagPagination", function(collection) {
|
eleventyConfig.addCollection("tagPagination", function(collection) {
|
||||||
@ -38,9 +52,6 @@ export default async function(eleventyConfig) {
|
|||||||
return tagMap;
|
return tagMap;
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Passthroughs */
|
|
||||||
eleventyConfig.addPassthroughCopy({"css": "assets/css"});
|
|
||||||
|
|
||||||
/* Plugins */
|
/* Plugins */
|
||||||
/* All filters from _config/filters.js */
|
/* All filters from _config/filters.js */
|
||||||
eleventyConfig.addPlugin(pluginFilters);
|
eleventyConfig.addPlugin(pluginFilters);
|
||||||
@ -85,9 +96,17 @@ export default async function(eleventyConfig) {
|
|||||||
/* Navigation */
|
/* Navigation */
|
||||||
eleventyConfig.addPlugin(eleventyNavigationPlugin);
|
eleventyConfig.addPlugin(eleventyNavigationPlugin);
|
||||||
|
|
||||||
|
/* `id` attributes */
|
||||||
|
eleventyConfig.addPlugin(IdAttributePlugin);
|
||||||
|
|
||||||
/* Syntax highlighting */
|
/* Syntax highlighting */
|
||||||
eleventyConfig.addPlugin(syntaxHighlight);
|
eleventyConfig.addPlugin(syntaxHighlight);
|
||||||
|
|
||||||
|
/* Shortcodes */
|
||||||
|
eleventyConfig.addShortcode("currentBuildDate", () => {
|
||||||
|
return (new Date()).toISOString();
|
||||||
|
});
|
||||||
|
|
||||||
/* Watch when serving */
|
/* Watch when serving */
|
||||||
eleventyConfig.addWatchTarget("css");
|
eleventyConfig.addWatchTarget("css");
|
||||||
};
|
};
|
||||||
|
|||||||
7
package-lock.json
generated
7
package-lock.json
generated
@ -12,10 +12,11 @@
|
|||||||
"@11ty/eleventy": "^3.1.2",
|
"@11ty/eleventy": "^3.1.2",
|
||||||
"@11ty/eleventy-img": "^6.0.4",
|
"@11ty/eleventy-img": "^6.0.4",
|
||||||
"@11ty/eleventy-navigation": "^1.0.5",
|
"@11ty/eleventy-navigation": "^1.0.5",
|
||||||
|
"@11ty/eleventy-plugin-bundle": "^3.0.7",
|
||||||
"@11ty/eleventy-plugin-rss": "^2.0.4",
|
"@11ty/eleventy-plugin-rss": "^2.0.4",
|
||||||
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
|
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
|
||||||
"@mdit/plugin-attrs": "^0.24.2",
|
"@mdit/plugin-attrs": "^0.24.2",
|
||||||
"@zachleat/heading-anchors": "^1.0.5",
|
"@zachleat/heading-anchors": "https://github.com/lee0c/heading-anchors/tarball/main",
|
||||||
"lodash-es": "^4.17.23",
|
"lodash-es": "^4.17.23",
|
||||||
"luxon": "^3.7.2"
|
"luxon": "^3.7.2"
|
||||||
}
|
}
|
||||||
@ -799,8 +800,8 @@
|
|||||||
},
|
},
|
||||||
"node_modules/@zachleat/heading-anchors": {
|
"node_modules/@zachleat/heading-anchors": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/@zachleat/heading-anchors/-/heading-anchors-1.0.5.tgz",
|
"resolved": "https://github.com/lee0c/heading-anchors/tarball/main",
|
||||||
"integrity": "sha512-hsAljmm6py9VEf6ToKGyQJweemQJM4bI75TTTbwRYIrasCm66ajJDhWYpgZJM1B+8KSop371RDhDASYl3Q4y9g==",
|
"integrity": "sha512-DQz11XHUNEXzwq8GBedqBVBYGjtdSjWDgcXQrg4bcbS9N3qwJZFhi6Sj4UnzQD7eQOEejCvxTzldS9iRi+rQzg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
"description": "Lee's personal website, take 2, built with 11ty",
|
"description": "Lee's personal website, take 2, built with 11ty",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"build": "rm -rf _site && npx @11ty/eleventy",
|
||||||
"start": "rm -rf _site && npx @11ty/eleventy --serve --quiet"
|
"start": "rm -rf _site && npx @11ty/eleventy --serve --quiet"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
@ -14,10 +15,11 @@
|
|||||||
"@11ty/eleventy": "^3.1.2",
|
"@11ty/eleventy": "^3.1.2",
|
||||||
"@11ty/eleventy-img": "^6.0.4",
|
"@11ty/eleventy-img": "^6.0.4",
|
||||||
"@11ty/eleventy-navigation": "^1.0.5",
|
"@11ty/eleventy-navigation": "^1.0.5",
|
||||||
|
"@11ty/eleventy-plugin-bundle": "^3.0.7",
|
||||||
"@11ty/eleventy-plugin-rss": "^2.0.4",
|
"@11ty/eleventy-plugin-rss": "^2.0.4",
|
||||||
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
|
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
|
||||||
"@mdit/plugin-attrs": "^0.24.2",
|
"@mdit/plugin-attrs": "^0.24.2",
|
||||||
"@zachleat/heading-anchors": "^1.0.5",
|
"@zachleat/heading-anchors": "https://github.com/lee0c/heading-anchors/tarball/main",
|
||||||
"lodash-es": "^4.17.23",
|
"lodash-es": "^4.17.23",
|
||||||
"luxon": "^3.7.2"
|
"luxon": "^3.7.2"
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 578 KiB |
BIN
src/img/about/duckies.png
Normal file
BIN
src/img/about/duckies.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.4 MiB |
BIN
src/img/about/kestrel.png
Normal file
BIN
src/img/about/kestrel.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.3 MiB |
BIN
src/img/about/koi-pond.jpg
Normal file
BIN
src/img/about/koi-pond.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 283 KiB |
@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
layout: page-lists.njk
|
||||||
pagination:
|
pagination:
|
||||||
data: collections.posts
|
data: collections.posts
|
||||||
size: 13
|
size: 13
|
||||||
@ -9,8 +10,10 @@ eleventyNavigation:
|
|||||||
order: 3
|
order: 3
|
||||||
icon: fa fa-solid fa-crow
|
icon: fa fa-solid fa-crow
|
||||||
title: home
|
title: home
|
||||||
layout: page.njk
|
permalink: index.html
|
||||||
---
|
---
|
||||||
|
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
|
||||||
|
|
||||||
{% include "postlist.njk" %}
|
{% include "postlist.njk" %}
|
||||||
|
|
||||||
{# idk why these are backwards either #}
|
{# idk why these are backwards either #}
|
||||||
|
|||||||
@ -1,4 +1,6 @@
|
|||||||
---
|
---
|
||||||
|
layout: page-lists.njk
|
||||||
|
permalink: gallery/index.html
|
||||||
pagination:
|
pagination:
|
||||||
data: collections["gallery"]
|
data: collections["gallery"]
|
||||||
size: 13
|
size: 13
|
||||||
@ -11,7 +13,9 @@ title: gallery
|
|||||||
icon: fa-regular fa-images
|
icon: fa-regular fa-images
|
||||||
label: view the gallery
|
label: view the gallery
|
||||||
---
|
---
|
||||||
<p>the gallery page is for finished art</p>
|
|
||||||
|
<p class="centered">the gallery page is for finished art</p>
|
||||||
|
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
|
||||||
|
|
||||||
{% include "postlist.njk" %}
|
{% include "postlist.njk" %}
|
||||||
|
|
||||||
@ -1,4 +1,6 @@
|
|||||||
---
|
---
|
||||||
|
layout: page-lists.njk
|
||||||
|
permalink: reference/index.html
|
||||||
pagination:
|
pagination:
|
||||||
data: collections["reference"]
|
data: collections["reference"]
|
||||||
size: 13
|
size: 13
|
||||||
@ -6,12 +8,14 @@ pagination:
|
|||||||
alias: postlist
|
alias: postlist
|
||||||
eleventyNavigation:
|
eleventyNavigation:
|
||||||
key: reference
|
key: reference
|
||||||
order: 2
|
order: 1
|
||||||
title: reference
|
title: reference
|
||||||
icon: fa-regular fa-folder-open
|
icon: fa-regular fa-folder-open
|
||||||
label: read reference posts
|
label: read reference posts
|
||||||
---
|
---
|
||||||
<p>the reference page is for informational posts</p>
|
|
||||||
|
<p class="centered">the reference page is for informational posts</p>
|
||||||
|
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
|
||||||
|
|
||||||
{% include "postlist.njk" %}
|
{% include "postlist.njk" %}
|
||||||
|
|
||||||
@ -1,11 +1,11 @@
|
|||||||
---
|
---
|
||||||
layout: page.njk
|
layout: page-lists.njk
|
||||||
pagination:
|
pagination:
|
||||||
data: collections.tagPagination
|
data: collections.tagPagination
|
||||||
size: 1
|
size: 1
|
||||||
alias: tag
|
alias: tag
|
||||||
eleventyComputed:
|
eleventyComputed:
|
||||||
permalink: /tag/{{ tag.tagName | slugify }}/{% if tag.pageNumber %}{{ tag.pageNumber + 1 }}/{% endif %}
|
permalink: /tags/{{ tag.tagName | slugify }}/{% if tag.pageNumber %}{{ tag.pageNumber + 1 }}/{% endif %}
|
||||||
title: "tag: {{ tag.tagName }}"
|
title: "tag: {{ tag.tagName }}"
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
27
src/meta/tags.njk
Normal file
27
src/meta/tags.njk
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
---
|
||||||
|
layout: page-lists.njk
|
||||||
|
permalink: tags/index.html
|
||||||
|
title: all tags
|
||||||
|
---
|
||||||
|
|
||||||
|
<ul id="taglist">
|
||||||
|
{% for tag in collections | getKeys | removeBasicTags | sortAlphabetically %}
|
||||||
|
{% set tagUrl %}/tags/{{ tag | slugify }}/{% endset %}
|
||||||
|
<li class="tag">
|
||||||
|
<a href="{{ tagUrl }}" class="taglink">
|
||||||
|
<div class="tag-imgs">
|
||||||
|
{% for i in range(0, 4) %}
|
||||||
|
{% if collections[tag][i].data.image %}
|
||||||
|
<img src="/img/{{ collections[tag][i].data.image.src }}" alt="{{ collections[tag][i].data.image.alt }}">
|
||||||
|
{% else %}
|
||||||
|
<div class="missing-image"></div>
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
<h2>{{ tag }}</h2>
|
||||||
|
{% set numPosts = collections[tag].length %}
|
||||||
|
<p><span class="tagcount">({{ numPosts }} post{% if numPosts > 1 %}s{% endif %})</span></p>
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
eleventyNavigation:
|
|
||||||
key: about
|
|
||||||
order: 4
|
|
||||||
title: about
|
|
||||||
icon: fa-regular fa-user
|
|
||||||
label: about Lee
|
|
||||||
---
|
|
||||||
52
src/pages/about.njk
Normal file
52
src/pages/about.njk
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
---
|
||||||
|
eleventyNavigation:
|
||||||
|
key: about
|
||||||
|
order: 4
|
||||||
|
title: about
|
||||||
|
icon: fa-regular fa-user
|
||||||
|
label: about Lee
|
||||||
|
---
|
||||||
|
|
||||||
|
<p>My name is Lee Cattarin. I use he or ze pronouns.</p>
|
||||||
|
|
||||||
|
<p>I'm a programmer (<a href="/resume/">are you looking for a resume?</a>), artist&crafter - knitting, spinning yarn, stamp carving/printmaking, cardmaking & papercrafts, bookbinding, leatherworking - bread baker, guitar player, and probably a lot of other things.</p>
|
||||||
|
|
||||||
|
<img src="/img/about/koi-pond.jpg" alt="A koi pond in fall afternoon light. A slender white person in a knitted dark teal sweater crouches in front of the pond and extends hir hand towards the surface of the water. Several curious koi are arriving to see what the matter is, and one white koi has stuck its face a bit out of the water to reach toward hir hand.">
|
||||||
|
|
||||||
|
<p>As of November 2023, my wife Brooke Osment and I have a art store: Riverside Refuge Studio. You can find various store links, or other ways to connect, on my <a href="/contact">contact page</a>. We're based out of Vashon, WA, USA, and ship internationally.</p>
|
||||||
|
|
||||||
|
<h2>pets</h2>
|
||||||
|
|
||||||
|
<p>We have a dog...</p>
|
||||||
|
|
||||||
|
<img src="/img/about/kestrel.png" alt="4 collaged pictures of Kestrel the Malinois mutt, a big tan dog with a thick ruff and half floppy, half pointy ears. In the pictures, he rolls on his back in the grass, looks snobbily at the camera with one ear flopping, looks off to one side, and sleeps in a big leather chair.">
|
||||||
|
|
||||||
|
<p>...and six ducks.</p>
|
||||||
|
|
||||||
|
<img src="/img/about/duckies.png" alt="2 pictures that show all six ducks, each duck labeled with their name. In the first image, Sparrow (Golden 300, a light brown breed that looks similar to female mallards) and Puffin (Swedish Black, black with a white bib and beautiful iridescence) come up to eat from my hand. In the second image, Chickadee (Magpie, black and white splotched) is up front looking to one side, and behind her are Dodo (Silver Runner, white and grey), Emu (Fawn & White Runner, white and pale tan), and Kiwi (Chocolate Runner, dark brown all over), with Sparrow and Puffin partially visible behind.">
|
||||||
|
|
||||||
|
<h2>webrings</h2>
|
||||||
|
|
||||||
|
{% set id = "css-joy-webring" %}
|
||||||
|
{% set name = "CSS Joy webring" %}
|
||||||
|
{% set url = "https://cs.sjoy.lol/" %}
|
||||||
|
{% set prev = "https://webri.ng/webring/cssjoy/previous?via=https://leecat.art" %}
|
||||||
|
{% set next = "https://webri.ng/webring/cssjoy/next?via=https://leecat.art" %}
|
||||||
|
{% set rand = "https://webri.ng/webring/cssjoy/random?via=https://leecat.art" %}
|
||||||
|
{% include "webring.njk" %}
|
||||||
|
|
||||||
|
{% set id = "a11y-webring-club" %}
|
||||||
|
{% set name = "a11y-webring.club" %}
|
||||||
|
{% set url = "https://a11y-webring.club/" %}
|
||||||
|
{% set prev = "https://a11y-webring.club/prev" %}
|
||||||
|
{% set next = "https://a11y-webring.club/next" %}
|
||||||
|
{% set rand = "https://a11y-webring.club/random" %}
|
||||||
|
{% include "webring.njk" %}
|
||||||
|
|
||||||
|
{% set id = "no-ai-webring" %}
|
||||||
|
{% set name = "No AI webring" %}
|
||||||
|
{% set url = "https://baccyflap.com/noai/" %}
|
||||||
|
{% set prev = "https://baccyflap.com/noai/?prv&s=lee" %}
|
||||||
|
{% set next = "https://baccyflap.com/noai/?nxt&s=lee" %}
|
||||||
|
{% set rand = "https://baccyflap.com/noai/?rnd" %}
|
||||||
|
{% include "webring.njk" %}
|
||||||
@ -2,8 +2,9 @@
|
|||||||
title: colophon
|
title: colophon
|
||||||
---
|
---
|
||||||
|
|
||||||
|
This is v2 of my personal website, build with [{{ eleventy.generator }}](https://www.11ty.dev/){target="_blank" rel="external"}. It's been hand-coded from the ground up.
|
||||||
|
|
||||||
This site is based on, though long diverged from, [Millennial](https://lenpaul.github.io/Millennial/){target="_blank" rel="external"}, a minimalist Jekyll theme for running a blog or publication by Paul Le. It is built using [Jekyll](https://jekyllrb.com/){target="_blank" rel="external"}, a static site generator. It runs on GitHub Pages.
|
v1 of this site began in 2022 and was based on [Millennial](https://lenpaul.github.io/Millennial/){target="_blank" rel="external"}, a minimalist Jekyll theme for running a blog or publication by Paul Le.
|
||||||
|
|
||||||
The fonts are [Atkinson Hyperlegible Next and Atkinson Hyperlegible Mono](https://brailleinstitute.org/freefont){target="_blank" rel="external"} for standard text and monospace respectively, specifically designed for low-vision readers to improve character recognition. Also they look neat :)
|
The fonts are [Atkinson Hyperlegible Next and Atkinson Hyperlegible Mono](https://brailleinstitute.org/freefont){target="_blank" rel="external"} for standard text and monospace respectively, specifically designed for low-vision readers to improve character recognition. Also they look neat :)
|
||||||
|
|
||||||
@ -12,10 +13,6 @@ Thank you to some lovely friends for their feedback and help with the site! You
|
|||||||
- [Lenny](http://www.wondra.codes/){target="_blank" rel="external"}, especially for their HTML/CSS and accessibility expertise
|
- [Lenny](http://www.wondra.codes/){target="_blank" rel="external"}, especially for their HTML/CSS and accessibility expertise
|
||||||
- [Shir](https://shirgoldberg.com/){target="_blank" rel="external"}
|
- [Shir](https://shirgoldberg.com/){target="_blank" rel="external"}
|
||||||
|
|
||||||
|
You can [find the accessibility statement here](/accessibility). You can also [explore the sitemap](/sitemap.xml). If you'd like, you can view the [site's palette](/palette) or the [style overview](/style).
|
||||||
|
|
||||||
This site is created [without the use of generative AI](https://declare-ai.org/1.0.0/none.html){target="_blank" rel="external"}.
|
This site is created [without the use of generative AI](https://declare-ai.org/1.0.0/none.html){target="_blank" rel="external"}.
|
||||||
|
|
||||||
You can [find the accessibility statement for leecat.art here](/accessibility).
|
|
||||||
|
|
||||||
If you'd like, you can view the [site palette](/palette) or the [style overview](/style).
|
|
||||||
|
|
||||||
[The sitemap can be found here](/sitemap.xml).
|
|
||||||
|
|||||||
@ -6,3 +6,114 @@ title: contact
|
|||||||
icon: fa-solid fa-envelope-open-text
|
icon: fa-solid fa-envelope-open-text
|
||||||
label: contact Lee
|
label: contact Lee
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## contact me
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-signal-messenger"></i> signal</dt>
|
||||||
|
<dd><a href="https://signal.me/#eu/PcJ86iNQeAbC-SFbxqI00gFQb6zL4Y6QDCsFDU2mokM4K40djsdNYa3hJAee79ll">inherentlee.13</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-envelope"></i> email</dt>
|
||||||
|
<dd><a href="mailto:lee.cattarin@gmail.com" target="_blank">lee dot cattarin at gmail dot com</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-mobile-retro"></i> text (no phone calls!)</dt>
|
||||||
|
<dd>seven seven four, two four nine, zero five eight six</dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-discord"></i> discord</dt>
|
||||||
|
<dd>inherentlee</dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-envelopes-bulk"></i> snail mail</dt>
|
||||||
|
<dd>message me for address!</dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-signature"></i> guestbook?</dt>
|
||||||
|
<dd><a href="/guestbook">guestbook.</a></dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
## socials
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-mastodon"></i> the fediverse/mastodon</dt>
|
||||||
|
<dd><a rel="me" href="https://flipping.rocks/@inherentlee" target="_blank">@inherentlee@flipping.rocks</a> and <a rel="me" href="https://weirder.earth/@inherentlee" target="_blank">@inherentlee@weirder.earth</a> (weirder.earth largely unused)</dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-rss"></i> rss</dt>
|
||||||
|
<dd><a href="/feed.xml">feed</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-icicles"></i> codeberg</dt>
|
||||||
|
<dd><a href="https://codeberg.org/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-github"></i> github</dt>
|
||||||
|
<dd><a href="https://github.com/lee0c" target="_blank">lee0c</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-ravelry"></i> ravelry</dt>
|
||||||
|
<dd><a href="https://ravelry.com/people/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-twitch"></i> twitch</dt>
|
||||||
|
<dd><a href="https://twitch.tv/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## shops
|
||||||
|
|
||||||
|
if pricing is an issue for you, reach out and we can work out sliding scale options - or an art trade!
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><i aria-hidden="true" class="fa-regular fa-square"></i> square</dt>
|
||||||
|
<dd><a href="https://riverside-refuge.square.site/" target="_blank">Riverside Refuge Studio</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-store"></i> faire (wholesale)</dt>
|
||||||
|
<dd><a href="https://faire.com/direct/riversiderefugestudio" target="_blank">Riverside Refuge Studio</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-mug-saucer"></i> kofi (now the home of <a href="https://fedizinefest.fyi">FediZineFest 2025</a> and <a href="https://rescue-trans-rescue.quest" target="_blank">Rescue Trans Rescue</a>)</dt>
|
||||||
|
<dd><a href="https://ko-fi.com/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
### payment methods
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><i aria-hidden="true" class="fa-solid fa-comment-dollar"></i> venmo</dt>
|
||||||
|
<dd><a href="https://www.venmo.com/u/lee-cattarin" target="_blank">lee-cattarin</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-paypal"></i> paypal</dt>
|
||||||
|
<dd><a href="https://paypal.me/leecattarin?country.x=US&locale.x=en_US" target="_blank">leecattarin</a></dd>
|
||||||
|
</dl>
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## in physical stores!
|
||||||
|
|
||||||
|
### Colorado
|
||||||
|
|
||||||
|
#### Denver
|
||||||
|
|
||||||
|
- [(dis)obedience](https://www.disobediencedenver.com){:target="_blank"}: stickers, pins, cards
|
||||||
|
|
||||||
|
### Oregon
|
||||||
|
|
||||||
|
#### Beaverton
|
||||||
|
|
||||||
|
- [Forager Vintage](https://foragervintage.com/){:target="_blank"}: stickers, pins, cards
|
||||||
|
|
||||||
|
### Washington
|
||||||
|
|
||||||
|
#### Port Orchard
|
||||||
|
|
||||||
|
- [Aphrodisia Boutique](https://www.aphrodisia.boutique/){:target="_blank"}: stickers, pins, cards, prints, leather goods (impact toys, cuffs, potentially harnesses)
|
||||||
|
|
||||||
|
#### Seattle
|
||||||
|
|
||||||
|
- [Push/Pull](https://www.pushpullseattle.com/){:target="_blank"}: stickers, pins, cards
|
||||||
|
- [Standard Goods Ballard](https://thestandardgoods.com/pages/ballard){:target="_blank"}: stickers
|
||||||
|
- [Standard Goods Capitol Hill](https://thestandardgoods.com/pages/capitol-hill){:target="_blank"}: stickers
|
||||||
|
|
||||||
|
#### Tacoma
|
||||||
|
|
||||||
|
- Anna's Anomalies (Sanford and Sons Antiques, 743 Broadway, Tacoma, WA, 98402): stickers, pins, cards, prints
|
||||||
|
|
||||||
|
#### Vashon
|
||||||
|
|
||||||
|
- [Vashon Made (formerly Starving Artist Works) (facebook)](https://www.facebook.com/SawStarvingArtistWorks/){:target="_blank"}: stickers, cards, prints, wallets, handbound books, yarn
|
||||||
|
- [Standard Goods Vashon](https://thestandardgoods.com/pages/vashon){:target="_blank"}: stickers
|
||||||
|
- [Vashon Pharmacy](https://vashonpharmacy.com/){:target="_blank"}: cards
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## not online or online unreliably
|
||||||
|
|
||||||
|
<dl>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-linkedin"></i> linkedin</dt>
|
||||||
|
<dd><a href="https://www.linkedin.com/in/lee-cattarin/" target="_blank">Lee Cattarin</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-instagram"></i> instagram</dt>
|
||||||
|
<dd><a href="https://instagram.com/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-facebook"></i> facebook</dt>
|
||||||
|
<dd><a href="https://www.facebook.com/lee.cattarin.50/" target="_blank">Lee Cattarin</a></dd>
|
||||||
|
<dt><i aria-hidden="true" class="fa-brands fa-twitter"></i> twitter</dt>
|
||||||
|
<dd><a href="https://twitter.com/inherentlee" target="_blank">inherentlee</a></dd>
|
||||||
|
</dl>
|
||||||
|
|||||||
67
src/pages/guestbook.md
Normal file
67
src/pages/guestbook.md
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
---
|
||||||
|
title: guestbook
|
||||||
|
---
|
||||||
|
guestbook entries are manually added and moderated :)
|
||||||
|
|
||||||
|
yes, you may sign again even if you've been here before - just no spamming please!
|
||||||
|
|
||||||
|
## write
|
||||||
|
|
||||||
|
if the embed below is not working for you, you can [open the guestbook form in a new tab](https://airtable.com/app1YuM4uE4sRTYgh/pag4JzOylrLoLy4AS/form){:target="_blank"} or just [contact me any way you want](/contact) with your desired message
|
||||||
|
|
||||||
|
<iframe class="airtable-embed" src="https://airtable.com/embed/app1YuM4uE4sRTYgh/pag4JzOylrLoLy4AS/form" frameborder="0" onmousewheel="" width="100%" height="533" style="background: transparent;"></iframe>
|
||||||
|
|
||||||
|
## read
|
||||||
|
|
||||||
|
J'myle Koretz on <time datetime="2025-05-21">21 May 2025</time>:
|
||||||
|
> It was delightful to meet you at the Vashon art walk a couple weekends back. Kestrel was awesome, and your [Brooke's] jackets were so cool!
|
||||||
|
|
||||||
|
Jack on <time datetime="2024-12-01">1 December 2024</time>:
|
||||||
|
> All the things you make and do are so cool and I feel so lucky every time I get to see them (including the ones that now live in my home!)
|
||||||
|
|
||||||
|
hello on <time datetime="2024-12-01">1 December 2024</time>:
|
||||||
|
> thanks for being gay and weird pal
|
||||||
|
|
||||||
|
Fén (Spirits) on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hi you make really good art and crafts and have been awesome to get to know ^^ Keep on keeping on~
|
||||||
|
|
||||||
|
Olive on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hi! You're cool :))
|
||||||
|
|
||||||
|
Fern (Rainbow) on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> I think you're awesome and this is really impressive 🥺
|
||||||
|
|
||||||
|
handmade ghost on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Everything Lee makes is a gift to the world--just knowing ze made something new brings me joy and sends me scrambling to this site!
|
||||||
|
|
||||||
|
[jay](jaygrant.us){:target="_blank"} on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> EGG
|
||||||
|
|
||||||
|
pqqq on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hello from Fedi! Your site is absolutely wonderful, and I love that you're adding a guestbook, too!!
|
||||||
|
|
||||||
|
Morgan on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> You make good art and good takes on gender 💜
|
||||||
|
|
||||||
|
[Lisa](@mycrowgirl@mastodon.social){:target="_blank"} on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Ask not for whom the snoot is booped. It is booped for weevils.
|
||||||
|
|
||||||
|
nathanlovestrees on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> honk!
|
||||||
|
|
||||||
|
[✨pencilears✨](https://pencilears.eternalaugust.net/comic/){:target="_blank"} on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hello! I'm glad we're still doing guest books on websites.
|
||||||
|
|
||||||
|
[brhfl](https://brhfl.com){:target="_blank"} on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> hey hi! just giving you some test data and also basking in the nostalgia of a guestbook :)
|
||||||
|
|
||||||
|
Eedlipherus C. Bigribs on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Signing the guestbook so you have data to format on the page lyao.
|
||||||
|
>
|
||||||
|
> And this is a second paragraph, because, honestly, this is more interesting than the QA I get paid to do, so I'll just make this bit long enough to wrap for a few lines, yep, maybe a little bit more, uh huh, that's right, eat your heart out, Lorem Ipsum.
|
||||||
|
|
||||||
|
jade on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hi Lee!
|
||||||
|
|
||||||
|
alex tax1a on <time datetime="2024-09-06">6 September 2024</time>:
|
||||||
|
> Hi!! signing the guestbook, so you have at least one datum.
|
||||||
13
src/pages/palette.njk
Normal file
13
src/pages/palette.njk
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
title: palette
|
||||||
|
---
|
||||||
|
{% css %}{% include "css/palette.css" %}{% endcss %}
|
||||||
|
|
||||||
|
<p class="color" id="dark">#2e303e</p>
|
||||||
|
<p class="color" id="dark-alt">#3c3f52</p>
|
||||||
|
<p class="color" id="light">#ebeeef</p>
|
||||||
|
<p class="color" id="light-alt">#dbe1e3</p>
|
||||||
|
<p class="color" id="teal-dark">#18737b</p>
|
||||||
|
<p class="color" id="teal-light">#25b0bc</p>
|
||||||
|
<p class="color" id="pink-dark">#94195d</p>
|
||||||
|
<p class="color" id="pink-light">#ee9fcb</p>
|
||||||
201
src/pages/resume.html
Normal file
201
src/pages/resume.html
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
---
|
||||||
|
title: resume
|
||||||
|
layout: resume.njk
|
||||||
|
---
|
||||||
|
<div class="resume">
|
||||||
|
<h1 class="centered upper">Lee Cattarin</h1>
|
||||||
|
|
||||||
|
<p class="centered">
|
||||||
|
he/him or ze/hir • Vashon, WA 98070
|
||||||
|
<br/>
|
||||||
|
<a href="mailto:lee.cattarin@gmail.com?subject=Resume%20inquiry">lee.cattarin@gmail.com</a> • <a href="/">this very website</a> • <a href="https://linkedin.com/in/lee-cattarin" target="_blank">linkedin.com/in/lee-cattarin</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h2 class="centered upper">Platforms Engineer</h2>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Design-oriented platforms/infrastructure engineer with a well-rounded background in algorithms, UI/UX, observabilty, databases, and accessibility. Consistent customer focus with strong communication skills and a passion for sharing knowledge.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2 class="centered upper" id="toolkit">Toolkit</h2>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Git, bash, and the terminal</li>
|
||||||
|
<li>Containers and Kubernetes</li>
|
||||||
|
<li>Terraform, Bicep, and infrastructure deployment</li>
|
||||||
|
<li>GitHub Actions and other pipelines</li>
|
||||||
|
<li>HTML/CSS, Javascript, and UI/UX design</li>
|
||||||
|
<li>Languages like Go, C, and Python</li>
|
||||||
|
<li>Accessiblity knowledge and thoughtful design</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2 class="centered upper" id="experience">Experience</h2>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<p><b>Microsoft,</b> Redmond, WA</p>
|
||||||
|
<p class="col2"><time datetime="2018-08">August 2018</time> – <time datetime="2025-07">July 2025</time></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Software Development Engineer I & II</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Worked on green- and brown-field projects with customers, solving emerging problems in infrastructure, devOps, and LLM/human interaction. Wrote reports on product feedback to relay to product teams and improved documentation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Contributed UI/UX, algorithm, and database design to a new human-in-the-loop approach to LLM form automation, ensuring both that content was effectively reviewed and that auditing was smooth.</li>
|
||||||
|
<li>Deployed and configured Kubernetes for many scenarios, handling monitoring and observability, scaling, traffic routing, security and policy, Windows container support, and more.</li>
|
||||||
|
<li>Maintained team working agreements to ensure team unity and consistency. Shaped team processes and documentation to improve clarity and speed up onboarding.</li>
|
||||||
|
<li>Improved Azure and open source documentation with new, updated, and corrected information.</li>
|
||||||
|
<li>Coached multiple learning-oriented hackathons to ensure broader community understanding and adoption of Azure services.</li>
|
||||||
|
<li>Presented to groups of 10–100 on backend accessibility and queer/trans education.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<p><b>Riverside Refuge Studio,</b> Vashon, WA</p>
|
||||||
|
<p class="col2"><time datetime="2023-10">October 2023</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Co-owner and artist</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Maintains website, storefront, and inventory for a diverse set of artistic goods. Communicates with a range of customers, both digitally and in-person.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>Designs and creates art/crafts in a variety of mediums ranging from visual to functional.</li>
|
||||||
|
<li>Presents work in art shows in and around Seattle.</li>
|
||||||
|
<li>Runs booths or studio space at art fairs and markets.</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<p><b>Rensselaer Polytechnic Institute,</b> Troy, NY</p>
|
||||||
|
<p class="col2"><time datetime="2015-09">September 2015</time> – <time datetime="2017-12">December 2017</time></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Undergraduate Programming Mentor</h3>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Helped students debug and develop in Python and learn core programming concepts. Created daily quiz material and graded exams.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<p><b>Microsoft,</b> Redmond, WA</p>
|
||||||
|
<p class="col2"><time datetime="2017-06">June 2017</time> – <time datetime="2017-08">August 2017</time></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Software Development Engineering Intern</h3>
|
||||||
|
<p>
|
||||||
|
Developed a chatbot add-on for the Azure Android application.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2 class="centered upper" id="projects">Projects</h2>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>11ty Lessons (<a href="https://inherentlee.codeberg.page/lessons" target="_blank">inherentlee.codeberg.page/lessons</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2026-02">February 2026</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Designs, develops, and maintains Eleventy-based website that details lessons learned while building with Eleventy.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>Spoonfairies (<a href="https://inherentlee.codeberg.page/spoonfairies" target="_blank">inherentlee.codeberg.page/spoonfairies</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2026-02">February 2026</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Designs, develops, and maintains Eleventy-based website for a just-launching project to build community and help people find support.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>Siblinghood of the Traveling Greeting Card (<a href="https://siblinghood.quest" target="_blank">siblinghood.quest</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2025-11">November 2025</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Designs, develops, and maintains website. Manages communication and logistics for a ~40 person global community building project.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>Beall Greenhouses (<a href="https://beall-greenhouses-market.pages.dev" target="_blank">beall-greenhouses-market.pages.dev</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2025-10">October 2025</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Created logo. Designs, develops, and maintains website. Manages artist information for the Beall Greenhouses artist studios.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>leecat.art (you are here!) (<a href="/">leecat.art</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2022-10">October 2022</time> – Present</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Designs, maintains, and creates all content.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>FediZineFest (<a href="https://fedizinefest.fyi" target="_blank">fedizinefest.fyi</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2023-12">December 2023</time> – <time datetime="2025-07">July 2025</time></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Created and ran a global event for zine artists on the fediverse (Mastodon) for two years. Coordinated website, physical material shipping and logistics, payment, and marketing for a 40–50 person project.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="spacer"></div>
|
||||||
|
|
||||||
|
<div class="job">
|
||||||
|
<div class="two-col job-details">
|
||||||
|
<h3>Rescue Trans Rescue (<a href="https://rescue-trans-rescue.quest" target="_blank">rescue-trans-rescue.quest</a>)</h3>
|
||||||
|
<p class="col2"><time datetime="2024">2024</time></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Created a digital art exhibit and sale to raise money for charity. Coordinated ~30 artists to contribute physical and digital work as well as a collaborative sticker sheet. Raised ~2.3k for Trans Rescue.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h2 class="centered upper">Education</h2>
|
||||||
|
|
||||||
|
<p class="centered">
|
||||||
|
<b>Bachelor of Science — Computer Science</b>
|
||||||
|
<br/>
|
||||||
|
Rensselaer Polytechnic Institute, Troy, NY
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
@ -16,6 +16,14 @@ The number of pound signs determines the heading level.
|
|||||||
|
|
||||||
It's also important not to skip heading levels. Don't jump from a 2 to a 4 or similar.
|
It's also important not to skip heading levels. Don't jump from a 2 to a 4 or similar.
|
||||||
|
|
||||||
|
##### Heading level 5
|
||||||
|
|
||||||
|
You can use up to level 6!
|
||||||
|
|
||||||
|
###### Here's level 6
|
||||||
|
|
||||||
|
It's just unnecessary.
|
||||||
|
|
||||||
## Paragraphs
|
## Paragraphs
|
||||||
|
|
||||||
You'll notice that I am putting blank lines between headings and plain text. This is necessary, or they won't render correctly.
|
You'll notice that I am putting blank lines between headings and plain text. This is necessary, or they won't render correctly.
|
||||||
|
|||||||
140
src/posts/2026/2026-01-05-gallery-fake.md
Normal file
140
src/posts/2026/2026-01-05-gallery-fake.md
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
---
|
||||||
|
title: moving images two
|
||||||
|
image:
|
||||||
|
src: 2026/cormorant.jpg
|
||||||
|
alt: "Image unrelated to post. A cormorant, a type of black waterfowl, poses with wings spread on a buoy in Puget Sound. Off to the left, another bird floats."
|
||||||
|
tags:
|
||||||
|
- gallery
|
||||||
|
- software
|
||||||
|
- some
|
||||||
|
- more
|
||||||
|
- tags
|
||||||
|
---
|
||||||
|
|
||||||
|
## problem statement
|
||||||
|
|
||||||
|
today I decided to finally clean up the `assets/img` directory for this site. Since 2022, when I started this project, I've just been adding images directly to that directory with no further segmentation - messy of me, I know! It's gotten unwieldy and I'm starting to get worried about generic names leading to duplicates at some point, particularly for the non-gallery images where I have a tendency to [use](/stationery-exchange) [lots](/favorite-git-flag) [of](/trans-networks) [mushroom](/no-politics) [images](/domain-and-site-setup).
|
||||||
|
|
||||||
|
so it's time to move them into year-based folders. Let's talk about how I did that. `bash` away!
|
||||||
|
|
||||||
|
(want to [skip right to the completed script?](#result))
|
||||||
|
|
||||||
|
## find
|
||||||
|
|
||||||
|
let's start with the basics: a list of posts. `find` gets us everything under a specific directory - in this case, the `_posts` directory. We can filter out the directories a few different ways, but I piped the `find` output through a basic `grep` looking for `.md` in the filename.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
for FILE in $(find _posts | grep .md)
|
||||||
|
do
|
||||||
|
# TBD
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
## grep
|
||||||
|
|
||||||
|
`grep` can also help us get image names with the regex `"name:.+jpg|png"`. I add `name:` to the regex because there are *very occasionally* images that aren't the featured image for the post, and those don't fit the pattern of `name: <img>`. Since there's so few of those, I ended up handling them manually.
|
||||||
|
|
||||||
|
to make `grep` work with regex, it needs the `-E` flag.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# gives us
|
||||||
|
# name: <img>
|
||||||
|
# note the 4 spaces at the beginning of the line
|
||||||
|
IMAGE_LINE=$(cat $FILE | grep -E "name:.+jpg|png$")
|
||||||
|
```
|
||||||
|
|
||||||
|
## cut
|
||||||
|
|
||||||
|
that output gets us the full line of text that includes the image filename. Let's trim out what we actually want.
|
||||||
|
|
||||||
|
below, `-d` sets a delimiter, and `-f` chooses what field we want to return. Because there's 4 spaces before `name`, our field index is actually pretty high - `cut` is creating 4 empty strings.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
IMAGE=$(echo $IMAGE_LINE | cut -d ' ' -f 6 -)
|
||||||
|
```
|
||||||
|
|
||||||
|
or, for brevity:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
IMAGE=$(cat $FILE | grep -E "name:.+jpg|png$" | cut -d ' ' -f 6 -)
|
||||||
|
```
|
||||||
|
|
||||||
|
with `cut`, we can also get the year of the post:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
YEAR=$(echo $FILE | cut -d '/' -f 2 -)
|
||||||
|
```
|
||||||
|
|
||||||
|
## sed
|
||||||
|
|
||||||
|
there's two major things we need to do with the information we've gathered:
|
||||||
|
|
||||||
|
1. replace the image filename in-place in the post's markdown file
|
||||||
|
1. move the image file from its original location into a new directory
|
||||||
|
|
||||||
|
we can do replacement with `sed`, where our pattern should be something like this: `s/$IMAGE/$YEAR\/&\` (the `&` subs in the found string - in this case `$IMAGE`). We could also use comma separators if we don't want to escape the slash, like `s,$IMAGE,$YEAR/&,` - I did this for ease of reading.
|
||||||
|
|
||||||
|
by default, `sed` prints to standard output, so we'll tell it to edit in-place instead with `-i`. Here's our full `sed` command:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sed "s,$IMAGE,$YEAR/&," -i $FILE
|
||||||
|
```
|
||||||
|
|
||||||
|
## mving and shaking
|
||||||
|
|
||||||
|
(my mom thinks I'm funny.)
|
||||||
|
|
||||||
|
now we'll handle moving the image file from its original location into a new directory. let's create our image paths, source and destination:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
IMG_DIR=assets/img
|
||||||
|
NEW_IMAGE=$IMG_DIR/$YEAR/$IMAGE
|
||||||
|
IMAGE=$IMG_DIR/$IMAGE
|
||||||
|
```
|
||||||
|
|
||||||
|
trying to `mv` the images will immediately cause problems, because the year directories don't exist yet. A simple check gets us past that:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
if [ ! -d $IMG_DIR/$YEAR ]
|
||||||
|
then
|
||||||
|
mkdir $IMG_DIR/$YEAR
|
||||||
|
fi
|
||||||
|
```
|
||||||
|
|
||||||
|
finally, we can `mv` the image:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mv $IMAGE $NEW_IMAGE
|
||||||
|
```
|
||||||
|
|
||||||
|
## result
|
||||||
|
|
||||||
|
here's our final script:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
for FILE in $(find _posts | grep .md)
|
||||||
|
do
|
||||||
|
# parse image and year info
|
||||||
|
IMAGE=$(cat $FILE | grep -E "name:.+jpg|png$" | cut -d ' ' -f 6 -)
|
||||||
|
YEAR=$(echo $FILE | cut -d '/' -f 2 -)
|
||||||
|
|
||||||
|
# replace in-place in file
|
||||||
|
sed "s,$IMAGE,$YEAR/&," -i $FILE
|
||||||
|
|
||||||
|
# path creation
|
||||||
|
IMG_DIR=assets/img
|
||||||
|
NEW_IMAGE=$IMG_DIR/$YEAR/$IMAGE
|
||||||
|
IMAGE=$IMG_DIR/$IMAGE
|
||||||
|
|
||||||
|
# create dir for year if it doesn't exist
|
||||||
|
if [ ! -d $IMG_DIR/$YEAR ]
|
||||||
|
then
|
||||||
|
mkdir $IMG_DIR/$YEAR
|
||||||
|
fi
|
||||||
|
|
||||||
|
# move image
|
||||||
|
mv $IMAGE $NEW_IMAGE
|
||||||
|
done
|
||||||
|
```
|
||||||
|
|
||||||
|
questions? errors? [ping me!](/contact)
|
||||||
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Sample 0
|
|
||||||
date: 2026-02-17
|
|
||||||
tags:
|
|
||||||
- gallery
|
|
||||||
- test
|
|
||||||
image:
|
|
||||||
src: 2026/sample-0.jpg
|
|
||||||
alt: filler
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Sample 1
|
|
||||||
date: 2026-02-18
|
|
||||||
tags:
|
|
||||||
- gallery
|
|
||||||
- test
|
|
||||||
image:
|
|
||||||
src: 2026/sample-0.jpg
|
|
||||||
alt: filler
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Sample 2
|
|
||||||
date: 2026-02-19
|
|
||||||
tags:
|
|
||||||
- gallery
|
|
||||||
- test
|
|
||||||
image:
|
|
||||||
src: 2026/sample-0.jpg
|
|
||||||
alt: filler
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Sample 3
|
|
||||||
date: 2026-02-20
|
|
||||||
tags:
|
|
||||||
- gallery
|
|
||||||
- test
|
|
||||||
image:
|
|
||||||
src: 2026/sample-0.jpg
|
|
||||||
alt: filler
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
title: Sample 4
|
|
||||||
date: 2026-02-21
|
|
||||||
tags:
|
|
||||||
- gallery
|
|
||||||
- test
|
|
||||||
image:
|
|
||||||
src: 2026/sample-0.jpg
|
|
||||||
alt: filler
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user