Compare commits

..
234 Commits
Author SHA1 Message Date
inherentlee 230e86bf7c Merge branch 'main' into stickers
continuous-integration/drone/push Build is passing
2026-10-21 15:23:12 -07:00
inherentlee 32b055f328 note re samples 2026-10-21 15:21:37 -07:00
inherentlee 438d1a67e2 stickerbros 2026-10-21 15:15:12 -07:00
inherentlee cd7f525bac plaid dishtowels
continuous-integration/drone/push Build is passing
2026-10-19 13:09:35 -07:00
inherentlee 6933f11630 stickerapp 2026-10-17 19:35:31 -07:00
inherentlee 62dab04ee9 more about sticky brand ew 2026-10-15 11:24:07 -07:00
inherentlee e60d191e09 sticker update 2026-10-14 13:45:54 -07:00
inherentlee efe79ff639 Merge branch 'main' into stickers 2026-10-14 10:39:12 -07:00
inherentlee 4be20cccb3 border radius for blockquotes
continuous-integration/drone/push Build is passing
2026-10-14 10:38:57 -07:00
inherentlee aba74f280e some tweaks to git post
continuous-integration/drone/push Build is passing
2026-10-14 08:48:25 -07:00
inherentlee 0125216d96 add more aout remote commands
continuous-integration/drone/push Build is passing
2026-10-14 08:43:19 -07:00
inherentlee 6ee81d8784 small updates to git post
continuous-integration/drone/push Build is passing
2026-10-14 08:28:24 -07:00
inherentlee 2bfe616195 update fedizinefest
continuous-integration/drone/push Build is failing
2026-10-13 08:31:32 -07:00
inherentlee f9d8123b9d add header ids
continuous-integration/drone/push Build is passing
2026-10-13 08:30:50 -07:00
inherentlee c7ef4c701a sticker updates 2026-10-13 07:45:30 -07:00
inherentlee d8f3ea3430 add stickerapp 2026-10-10 11:16:25 -07:00
inherentlee a9b96e567e add bend print co samples 2026-10-09 15:46:26 -07:00
inherentlee bc1a51a4d5 add district dharma testimonial
continuous-integration/drone/push Build is passing
2026-10-06 09:52:56 -07:00
inherentlee 16c3ef1e26 audit fix 2026-10-06 09:52:44 -07:00
inherentlee efe153191a another tiny mobile tweak
continuous-integration/drone/push Build is passing
2026-10-06 09:03:41 -07:00
inherentlee 8c2c2231ac some size tweaks for headers on mobile
continuous-integration/drone Build is passing
2026-10-05 13:38:48 -07:00
inherentlee 62b1e448ea Merge branch 'main' into stickers 2026-10-05 13:31:36 -07:00
inherentlee d53198e1aa add sticker junkie, sticker robot, and vinyl disorder
continuous-integration/drone/push Build is running
2026-10-05 13:29:44 -07:00
inherentlee c6ec6b8f48 make urls easier to read font
continuous-integration/drone/push Build is passing
2026-10-04 11:17:32 -07:00
inherentlee 75909355ba couple of notes about samples
continuous-integration/drone/push Build is passing
2026-10-02 17:28:05 -07:00
inherentlee d5660455bd add drone trigger that requires main branch
continuous-integration/drone/push Build is passing
2026-10-02 12:59:15 -07:00
inherentlee 7df4c1ff8e more about sticker bunnies
continuous-integration/drone/push Build is passing
2026-10-02 12:54:06 -07:00
inherentlee d6c2bb9aa9 wording
continuous-integration/drone/push Build is passing
2026-10-02 09:57:23 -07:00
inherentlee 604a6787f4 sticker bunnies
continuous-integration/drone/push Build is passing
2026-10-01 18:55:54 -07:00
inherentlee 980cd0b3a6 update with stickergiant info
continuous-integration/drone/push Build is passing
2026-10-01 13:05:34 -07:00
inherentlee 5be42a4ff3 vinyl disorder and a few details 2026-10-01 08:53:36 -07:00
inherentlee 25c8e56a76 more re sticker ninja
continuous-integration/drone/push Build is passing
2026-09-30 17:44:29 -07:00
inherentlee 8752eeb904 sticker ninja details
continuous-integration/drone/push Build is passing
2026-09-30 17:41:40 -07:00
inherentlee b1135beddb update squarespace more
continuous-integration/drone/push Build is passing
2026-09-30 16:52:53 -07:00
inherentlee 84160a0574 update squarespace
continuous-integration/drone/push Build is passing
2026-09-30 16:51:12 -07:00
inherentlee 557308f3f9 sticker post wip
continuous-integration/drone/push Build is failing
2026-09-29 14:20:22 -07:00
inherentlee 382419e6d6 add toc to fediverse post
continuous-integration/drone/push Build is passing
2026-09-29 14:19:35 -07:00
inherentlee 66df77c32c remove old shop links 2026-09-29 10:01:11 -07:00
inherentlee a3e0ba5037 fedi intro post
continuous-integration/drone/push Build is passing
2026-09-28 09:38:52 -07:00
inherentlee 51d836c71b add to wong foo
continuous-integration/drone/push Build is passing
2026-09-23 20:25:08 -07:00
inherentlee 67e70e68ab remove scroll-margin-top since navbar is no longer sticky
continuous-integration/drone/push Build is passing
2026-09-23 19:29:19 -07:00
inherentlee b31e683786 i honestly don't know why this was working without this but i'm adding it just in case
continuous-integration/drone/push Build is passing
2026-09-23 14:47:53 -07:00
inherentlee 1bb26176ba tweak some breakpoints
continuous-integration/drone/push Build is passing
2026-09-21 16:08:11 -07:00
inherentlee a000d1c1b9 i'm not happy with this but it's better for width
continuous-integration/drone/push Build is passing
2026-09-21 15:55:44 -07:00
inherentlee cf26b06e3d update tree styling to box method
continuous-integration/drone/push Build is passing
2026-09-21 15:40:27 -07:00
inherentlee 5acda53f58 publish leatherworking zine with link to fzf post
continuous-integration/drone/push Build is passing
2026-09-21 13:55:29 -07:00
inherentlee f2bc045735 fedizinefest post
continuous-integration/drone/push Build is passing
2026-09-21 13:49:51 -07:00
inherentlee 3b1c5ffa88 SR fix
continuous-integration/drone/push Build is passing
2026-09-21 12:48:45 -07:00
inherentlee 0882fcda41 better images
continuous-integration/drone/push Build is passing
2026-09-21 12:46:38 -07:00
inherentlee 7d042abe1d fuck spacing and tabs all my homies hate spacing and tabs
continuous-integration/drone/push Build is passing
2026-09-21 12:27:30 -07:00
inherentlee f5bbda1f14 small edits
continuous-integration/drone/push Build is passing
2026-09-21 12:23:53 -07:00
inherentlee 9999775e44 tree style post
continuous-integration/drone/push Build is passing
2026-09-21 12:19:01 -07:00
inherentlee 463cabe793 update framer post pic 2026-09-21 12:18:48 -07:00
inherentlee 4aa7516cb9 fix hanging indent 2026-09-21 12:18:13 -07:00
inherentlee f49a7faa4d more contrasting focus outlines for toc
continuous-integration/drone/push Build is passing
2026-09-21 08:38:59 -07:00
inherentlee 2e26cefab2 tiny tweak to prevent gap
continuous-integration/drone/push Build is passing
2026-09-20 19:04:19 -07:00
inherentlee 870a6e5e0f prevent blockquotes interferring with toc
continuous-integration/drone/push Build is passing
2026-09-20 19:01:54 -07:00
inherentlee be364d7644 it's important that the comment have a slant rhyme
continuous-integration/drone/push Build is passing
2026-09-20 18:50:52 -07:00
inherentlee 06bcfc1522 toc tree styling
continuous-integration/drone/push Build is passing
2026-09-20 18:46:09 -07:00
inherentlee dd1943bcdd li line height matches p line height
continuous-integration/drone/push Build is passing
2026-09-20 15:13:17 -07:00
inherentlee bfa91ea19f big ol toc update
continuous-integration/drone/push Build is passing
2026-09-20 15:07:49 -07:00
inherentlee b4fbeffc41 new font omg
continuous-integration/drone/push Build is passing
2026-09-19 17:40:10 -07:00
inherentlee 25cf8a38ec fix sitemap size 2026-09-18 12:30:23 -07:00
inherentlee 5724f509a0 update resume
continuous-integration/drone/push Build is passing
2026-09-18 08:48:30 -07:00
inherentlee fe6956aaa3 mark down framer for complex keyboard interactions
continuous-integration/drone/push Build is passing
2026-09-17 17:59:08 -07:00
inherentlee 846ef7538f note re dropdowns in framer
continuous-integration/drone/push Build is passing
2026-09-17 17:57:33 -07:00
inherentlee f8aacdc85d note about dropdowns
continuous-integration/drone/push Build is passing
2026-09-17 17:04:46 -07:00
inherentlee 776218805a more notes about framer
continuous-integration/drone/push Build is passing
2026-09-17 12:03:26 -07:00
inherentlee 91c7f14113 add instructions just for completeness
continuous-integration/drone/push Build is passing
2026-09-17 08:18:27 -07:00
inherentlee 8bcdaeff52 idk these notes were wrong i guess 2026-09-17 08:16:38 -07:00
inherentlee 3e766eb519 find a few more target=_blank bits
continuous-integration/drone/push Build is passing
2026-09-17 08:02:47 -07:00
inherentlee 2ad41daa2e make leatherworking zine a draft
continuous-integration/drone/push Build is passing
2026-09-17 07:56:09 -07:00
inherentlee 7b248c24b9 Merge branch 'leatherworking-zine' 2026-09-17 07:55:34 -07:00
inherentlee abec70c655 add missing page 2026-09-17 07:55:26 -07:00
inherentlee 2d35768db9 preliminary squarespace findings
continuous-integration/drone/push Build is passing
2026-09-16 11:06:40 -07:00
inherentlee 30498307c8 npm audit fix
continuous-integration/drone/push Build is passing
2026-09-15 18:05:04 -07:00
inherentlee 953f651c4f draft
continuous-integration/drone/push Build is passing
2026-09-15 14:47:53 -07:00
inherentlee ee0a39333d package-lock.json update
continuous-integration/drone/push Build is passing
2026-09-14 18:17:10 -07:00
inherentlee a2fd1cb797 package.lock updates? 2026-09-14 18:11:59 -07:00
inherentlee 9889cf4adb fix og metadata
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2026-09-14 10:38:11 -07:00
inherentlee a3b9d20dfb small style and word fixes to framer accessibility 2026-09-12 10:53:25 -07:00
inherentlee 1a0898c214 update guestbook page to remove embed
continuous-integration/drone/push Build is passing
2026-09-12 10:50:34 -07:00
inherentlee 07bb31111f remove target=blank etc 2026-09-12 10:48:36 -07:00
inherentlee c517bb8d69 remove keyboard shortcut on smaller screens, this could be more complex 2026-09-12 10:43:57 -07:00
inherentlee 830c1a4666 clean up search output
continuous-integration/drone/push Build is passing
2026-09-12 10:13:43 -07:00
inherentlee 1a2850ca8c fix apostrophes in browser title bar
continuous-integration/drone/push Build is passing
2026-09-11 17:53:34 -07:00
inherentlee 96e70dbd2f bit of further cleanup of pf styles
continuous-integration/drone/push Build is passing
2026-09-11 11:55:51 -07:00
inherentlee 58da634ec7 search bar timeeee 2026-09-11 11:46:47 -07:00
inherentlee d8049a1f34 update fedilearns icon
continuous-integration/drone/push Build is passing
2026-09-10 14:22:46 -07:00
inherentlee 12ae5f9a4e houndstooth dishtowels
continuous-integration/drone/push Build is passing
2026-09-10 09:58:30 -07:00
inherentlee 672a03d4e9 some tweaks to color picker
continuous-integration/drone/push Build is passing
2026-09-09 14:02:59 -07:00
inherentlee 0e46e65034 color picker yay
continuous-integration/drone/push Build is passing
2026-09-09 13:37:35 -07:00
inherentlee 782912c8a6 tweak intro content for gallery, reference, home pages
continuous-integration/drone/push Build is passing
2026-09-08 16:18:11 -07:00
inherentlee 470a84429c add link to view all tags to tag pages
continuous-integration/drone/push Build is passing
2026-09-08 16:14:35 -07:00
inherentlee 05e40f0ea7 add patchwork wallet to highlights
continuous-integration/drone/push Build is passing
2026-09-08 16:12:24 -07:00
inherentlee 35841f26fd mouse purse
continuous-integration/drone/push Build is passing
2026-09-08 16:05:29 -07:00
inherentlee 3fc4468d09 add styling to sitemap
continuous-integration/drone/push Build is passing
2026-09-08 10:49:41 -07:00
inherentlee bbcdb5ee03 i only just realized my style page didn't have code highlighting woops
continuous-integration/drone/push Build is passing
2026-09-08 10:40:24 -07:00
inherentlee d663b851c9 small margin change to lists
continuous-integration/drone/push Build is passing
2026-09-08 10:34:16 -07:00
inherentlee 4ac0441c3d framer accessibliity post
continuous-integration/drone/push Build is passing
2026-09-08 10:26:01 -07:00
inherentlee f6620e19a4 remove dead link
continuous-integration/drone/push Build is passing
2026-09-08 10:25:24 -07:00
inherentlee df9b5e4c55 add framer, gen -> generative
continuous-integration/drone/push Build is passing
2026-09-08 09:14:49 -07:00
inherentlee f4a32e5292 remove extraneous css line and add framer to builders post
continuous-integration/drone/push Build is passing
2026-09-06 09:02:49 -07:00
inherentlee 01c0bf00a2 tag edits
continuous-integration/drone/push Build is passing
2026-08-30 09:25:45 -07:00
inherentlee ff03344b81 rainbow shawl from 2023
continuous-integration/drone/push Build is passing
2026-08-30 09:09:21 -07:00
inherentlee e437febdf8 change webring button spacing
continuous-integration/drone/push Build is passing
2026-08-28 11:59:53 -07:00
inherentlee 21858e5dd3 add birder subtract bread baker
continuous-integration/drone/push Build is passing
2026-08-28 11:56:28 -07:00
inherentlee a780e7cc9e black and red journal
continuous-integration/drone/push Build is passing
2026-08-26 17:04:09 -07:00
inherentlee d0cb1cf7f5 resume updates re fedizinefest 2026-08-26 17:03:47 -07:00
inherentlee cd30f192eb REMOVE Z
continuous-integration/drone/push Build is passing
2026-08-26 16:55:20 -07:00
inherentlee d246ba3437 add og url
continuous-integration/drone/push Build is passing
2026-08-25 18:37:19 -07:00
inherentlee 7abb27739e fix tag alignment on mobile post layout
continuous-integration/drone/push Build is passing
2026-08-25 13:13:12 -07:00
inherentlee 742d2b9666 fix errors in 11ty lessons post
continuous-integration/drone/push Build is passing
2026-08-20 17:21:42 -07:00
inherentlee 3ff187ae10 add woven shawl
continuous-integration/drone/push Build is passing
2026-08-20 17:11:59 -07:00
inherentlee 0ec803b447 change modal size 2026-08-20 17:11:48 -07:00
inherentlee 1863efa802 site builders v1
continuous-integration/drone/push Build is passing
2026-08-06 11:37:38 -07:00
inherentlee 153a90fb0a better table margins 2026-08-06 11:26:14 -07:00
inherentlee 0a5d393618 update alt for table runner
continuous-integration/drone/push Build is passing
2026-08-01 08:49:50 -07:00
inherentlee 532424c953 table runner
continuous-integration/drone/push Build is passing
2026-08-01 08:44:24 -07:00
inherentlee 9b5ee21bf7 update log cabin dishtowels 2026-08-01 08:44:07 -07:00
inherentlee 33ad5815a7 atom feed stylesheet
continuous-integration/drone/push Build is passing
2026-07-29 14:56:25 -07:00
inherentlee 7a30ee3216 more dishtowel deets
continuous-integration/drone/push Build is passing
2026-07-26 15:08:33 -07:00
inherentlee 88562bd766 log cabin dishtowels
continuous-integration/drone/push Build is passing
2026-07-26 14:50:07 -07:00
inherentlee 75d3a12bdc update signal
continuous-integration/drone/push Build is passing
2026-07-01 14:47:59 -07:00
inherentlee f488a6aa54 remove draft flag
continuous-integration/drone/push Build is passing
2026-06-30 16:28:29 -07:00
inherentlee 8c135a09c7 core css 2026-06-30 16:28:05 -07:00
inherentlee 7ede08fd43 fix categories on two posts
continuous-integration/drone/push Build is passing
2026-06-30 13:19:10 -07:00
inherentlee e80f340642 remove site folder
continuous-integration/drone/push Build is passing
2026-05-21 16:35:18 -07:00
inherentlee 4b43f76ac4 add ai declaration meta values 2026-05-21 16:33:50 -07:00
inherentlee 54b63df970 drone file
continuous-integration/drone/push Build is passing
2026-05-15 09:23:58 -07:00
inherentlee b40f41a5f7 add submodule 2026-05-15 09:23:40 -07:00
inherentlee 1cf7b8560e build 2026-05-14 09:32:29 -07:00
inherentlee ba5b01d084 improve copyright 2026-05-14 09:30:54 -07:00
inherentlee feaaeb30b7 build 2026-05-14 09:24:37 -07:00
inherentlee 4af8d68ac9 add all years in footer 2026-05-14 09:19:20 -07:00
inherentlee c51e5b502a gram reformat 2026-05-14 09:19:05 -07:00
inherentlee 6585b8e74d fix time zone issue 2026-05-14 09:18:15 -07:00
inherentlee 22d4c48b46 core css draft 2026-05-14 09:02:08 -07:00
inherentlee 18989f817f build 2026-05-14 08:57:06 -07:00
inherentlee 5dfaac6820 tweak sizing/margins of modal images 2026-05-14 08:56:32 -07:00
inherentlee 814d4efe8b build 2026-05-14 08:51:09 -07:00
inherentlee 0b0822d21b reorder contact page 2026-05-14 08:50:30 -07:00
inherentlee f1c073535d build 2026-05-14 08:46:01 -07:00
inherentlee 4f0a0f3969 move tabindex setting to modal controls 2026-05-14 08:45:31 -07:00
inherentlee c4b7faca88 build 2026-05-13 20:50:51 -07:00
inherentlee 68487ad342 tweak alpha value of close button 2026-05-13 20:50:25 -07:00
inherentlee 2b90da7572 build 2026-05-13 20:47:18 -07:00
inherentlee 58be723eef pointer for clickable images 2026-05-13 20:46:48 -07:00
inherentlee 72c5904c27 build 2026-05-13 20:44:22 -07:00
inherentlee e615e6a91f image modals for posts 2026-05-13 20:42:31 -07:00
inherentlee a56ca4c03e remove pdf link 2026-05-07 14:30:54 -07:00
inherentlee 9a483ad27c build 2026-05-06 11:04:35 -07:00
inherentlee 63e225aebc fedilearns 2026-05-06 11:04:05 -07:00
inherentlee 60c07e629b update fedilearns url 2026-05-05 17:27:08 -07:00
inherentlee ff1fa0a966 build 2026-05-05 13:32:00 -07:00
inherentlee 64007ea884 add fedilearns to resume 2026-05-05 13:00:41 -07:00
inherentlee 1108f38939 explicit favicon setting 2026-05-05 12:57:21 -07:00
inherentlee cddc20ad3d build 2026-05-04 15:39:47 -07:00
inherentlee 3a9095c4e8 couple small fixes: home title attr, add mising tag, move post topics up in postlist 2026-05-04 11:48:19 -07:00
inherentlee 914243feb9 move anchor links to aria-labelledby model 2026-05-04 08:35:44 -07:00
inherentlee 3f9e6727de fix page title in metadata 2026-05-04 08:21:35 -07:00
inherentlee f980c8c682 switch order of heading and image 2026-05-03 21:20:24 -07:00
inherentlee 8104cd4520 update signal link 2026-04-21 14:31:42 -07:00
inherentlee 4f38bbfc82 build last 4 commits 2026-04-09 07:41:16 -07:00
inherentlee 56736453fe resume wording 2026-04-09 07:40:47 -07:00
inherentlee c04993c983 mobile margins 2026-04-09 07:40:38 -07:00
inherentlee ed3a845a55 small colophon edits 2026-04-09 07:38:06 -07:00
inherentlee c8ce389065 spell things right omg 2026-04-09 07:34:56 -07:00
inherentlee c95b3c080a testimonial from mari 2026-04-07 15:37:23 -07:00
inherentlee c559aa9154 add testimonial 2026-04-07 10:00:40 -07:00
inherentlee a14753e656 build 2026-04-06 13:27:56 -07:00
inherentlee 82db8f8758 beall testimonial 2026-04-06 13:27:21 -07:00
inherentlee d434da450f wording 2026-04-06 13:24:22 -07:00
inherentlee 913f8469f3 build 2026-04-06 10:27:00 -07:00
inherentlee 4f12d9c5ac change how resume page is handled and add some testimonials 2026-04-06 10:26:22 -07:00
inherentlee e14261bf4d fix weird spaces 2026-03-27 12:35:25 -07:00
inherentlee 073ad660e4 ok finishing up the blur stuff and also building 2026-03-27 12:33:35 -07:00
inherentlee c6dcdacbec further reorder art shows page 2026-03-27 12:25:26 -07:00
inherentlee 8ab1cb687b blur adulty matieral 2026-03-27 12:23:26 -07:00
inherentlee ac1903c5a1 reorder art shows page 2026-03-27 12:23:04 -07:00
inherentlee bf677c3cdf add line to remove structural tags 2026-03-27 11:54:48 -07:00
inherentlee 8adb83d8a8 rel external for accessible image modals 2026-03-25 13:03:30 -07:00
inherentlee 0439f0478d build prev 2026-03-25 13:00:47 -07:00
inherentlee ebe2490fd3 accessible image modals crosses fingers 2026-03-25 13:00:13 -07:00
inherentlee 409ca37f74 wording tweak 2026-03-25 12:50:36 -07:00
inherentlee e129b26e63 build 2026-03-24 10:38:18 -07:00
inherentlee dc49b1cad5 update contact page 2026-03-24 10:37:53 -07:00
inherentlee 21e3dca187 build last two commits 2026-03-24 10:11:20 -07:00
inherentlee ff9eb09838 update headers to use code blocks again now that i fixed that 2026-03-24 10:10:57 -07:00
inherentlee ce6aa0fb00 tweak heading anchor styling 2026-03-24 10:10:16 -07:00
inherentlee f89f135f9b build prev and add draft handling 2026-03-24 09:58:14 -07:00
inherentlee 422a0e45e8 format on save plus: 1) update spoonfairies URL 2) remove 11ty Lessons link 2026-03-24 09:50:14 -07:00
inherentlee 191ee1a355 make code blocks responsive to containing block font size 2026-03-23 15:32:27 -07:00
inherentlee 43ccb40e0b update resume page with gryphon's roost 2026-03-19 15:03:42 -07:00
inherentlee b5aff7207e sitemap styling 2026-03-18 11:11:11 -07:00
inherentlee aa9951e68d build 2026-03-12 11:52:52 -07:00
inherentlee 35519d9d4b remove anchor from related posts section 2026-03-12 11:52:24 -07:00
inherentlee 43ae5c489e rename script 2026-03-07 10:31:53 -08:00
inherentlee b51e953a1b fix date zone 2026-03-02 07:49:22 -08:00
inherentlee 0e14d3ca72 build prev 2026-03-01 14:41:07 -08:00
inherentlee 50d4b61037 jesus h christ 2026-03-01 14:40:42 -08:00
inherentlee 73a0278392 update resume with freelance work 2026-02-25 18:10:11 -08:00
inherentlee b241cc14af move 11ty lessons on resume page 2026-02-25 14:37:31 -08:00
inherentlee 98c00bb1fd robots txt 2026-02-25 14:25:33 -08:00
inherentlee bfefa33f13 exclude tag redirect pages from sitemap 2026-02-21 13:11:30 -08:00
inherentlee 89ff36afc7 build prev 2026-02-21 13:09:59 -08:00
inherentlee afbf693d3b redirects for the old tag urls 2026-02-21 13:09:15 -08:00
inherentlee a3ba14abd2 build prev 2026-02-21 12:23:40 -08:00
inherentlee e45e9b0f7a remove anchors from related posts 2026-02-21 12:23:05 -08:00
inherentlee 3e61e004f4 add space above footer 2026-02-20 19:22:14 -08:00
inherentlee 58a412f002 build now 2026-02-20 14:35:54 -08:00
inherentlee 64db3a2446 FAVICON 2026-02-20 14:35:32 -08:00
inherentlee a03a1b6c52 update beall greenhouses url 2026-02-20 14:12:22 -08:00
inherentlee 7f5dc28cad remove excess note 2026-02-20 13:15:09 -08:00
inherentlee 7e95d9ff16 build prev 2026-02-20 12:24:10 -08:00
inherentlee 6e3bfd9a08 fix some accessibilty issues 2026-02-20 12:23:36 -08:00
inherentlee ae056c75bd built with last change 2026-02-20 12:01:30 -08:00
inherentlee 5c786b15d2 remove redundant text 2026-02-20 11:59:29 -08:00
inherentlee 2c3711fe1e woops 2026-02-20 11:57:19 -08:00
inherentlee f18e2f2078 woops i forgot the lang attribute lmao 2026-02-20 11:53:41 -08:00
inherentlee 9a566f99ab build 2026-02-20 08:46:50 -08:00
inherentlee 9db3d3b34c tweak navbar border width 2026-02-20 08:46:40 -08:00
inherentlee 9249a6e050 run build 2026-02-20 08:36:56 -08:00
inherentlee 7d1fe776c7 add related posts and update some styling 2026-02-20 08:36:46 -08:00
inherentlee c4b549bc75 update site 2026-02-20 08:02:52 -08:00
inherentlee 6203735ff8 note re if you're doing multiple widths 2026-02-20 08:01:41 -08:00
inherentlee 3848af101b don't let the live build overwrite the built files cause of the iamge handling 2026-02-19 22:20:03 -08:00
inherentlee 25f5d5897b new post on eleventy 2026-02-19 22:19:39 -08:00
inherentlee fc71c05327 let's keep good ol mogrify around 2026-02-19 21:13:56 -08:00
inherentlee d080981f2d remainder of site this should be fine right 2026-02-19 21:12:12 -08:00
inherentlee 778d323db9 img 2026-02-19 21:10:56 -08:00
inherentlee 6e33a3baca a-h of site pages 2026-02-19 21:09:25 -08:00
inherentlee 522842c2f0 we can add the site now 2026-02-19 21:07:45 -08:00
inherentlee ecd5de37f4 literally spacing and a semicolon 2026-02-19 21:07:01 -08:00
174 changed files with 4755 additions and 918 deletions

No files matched your search

+28
View File
@@ -0,0 +1,28 @@
kind: pipeline
type: docker
name: default
trigger:
branch:
- main
steps:
- name: build
image: node:current
environment:
REPOSITORY: leecat.art-site
GIT_USER: inherentlee
GIT_TOKEN:
from_secret: GIT_TOKEN
commands:
- git config credential.helper '!f() { echo username=$GIT_USER; echo "password=$GIT_TOKEN"; };f'
- git submodule update --remote --init --merge
- npm install
- npm run build
- apt-get update && apt-get install -y rsync
- rsync -uavh _site/ $REPOSITORY --delete --exclude .git
- cd $REPOSITORY
- git checkout main
- git config --global --add safe.directory /drone/src/$REPOSITORY
- git add -A
- git commit -m "drone build $(TZ=':America/Los_Angeles' date)"
- git push
+3 -3
View File
@@ -1,5 +1,5 @@
# eleventy output
_site
# npm
node_modules
# build
_site
+3
View File
@@ -0,0 +1,3 @@
[submodule "leecat.art-site"]
path = leecat.art-site
url = https://heckin.technology/inherentlee/leecat.art-site.git
+19 -1
View File
@@ -2,4 +2,22 @@
Lee Cattarin's personal website, v2. Built on Eleventy.
Not live yet.
## Install
```sh
npm i
# or
npm install
```
## Run locally
```sh
npm run dev
```
## Build website
```sh
npm run build
```
+71 -14
View File
@@ -1,35 +1,92 @@
import { DateTime } from "luxon";
export default function(eleventyConfig) {
export default function (eleventyConfig) {
// Return the keys used in an object
eleventyConfig.addFilter("getKeys", target => {
eleventyConfig.addFilter("getKeys", (target) => {
return Object.keys(target);
});
/* Exclude all posts with given URLs from a collection list */
eleventyConfig.addFilter(
"excludeFromCollection",
function (collection = [], urls = [this.ctx.page.url]) {
return collection.filter((post) => urls.indexOf(post.url) === -1);
},
);
/* Filter a collection by a set of tags, returning any that share one or more tags */
eleventyConfig.addFilter(
"filterByTags",
function (collection = [], ...requiredTags) {
return collection.filter((post) => {
return requiredTags.flat().some((tag) => post.data.tags.includes(tag));
});
},
);
/* Return n elements from a list */
eleventyConfig.addFilter("head", (collection = [], n) => {
if (!Array.isArray(collection) || collection.length === 0) {
return [];
}
if (n < 0) {
return collection.slice(n);
}
return collection.slice(0, n);
});
/* For <time> elements */
eleventyConfig.addFilter("htmlDateString", (dateObj) => {
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd');
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat("yyyy-LL-dd");
});
/* What it says on the tin */
eleventyConfig.addFilter("randomize", function (array) {
// Create a copy of the array to avoid modifying the original
let shuffledArray = array.slice();
// Fisher-Yates shuffle algorithm
for (let i = shuffledArray.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[shuffledArray[i], shuffledArray[j]] = [
shuffledArray[j],
shuffledArray[i],
];
}
return shuffledArray;
});
/* Human-readable dates */
eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => {
return DateTime.fromJSDate(dateObj, { zone: zone || "utc" })
.toLocaleString(DateTime.DATE_FULL);
eleventyConfig.addFilter("readableDate", (dateObj) => {
return DateTime.fromJSDate(dateObj, { zone: "utc" }).toLocaleString(
DateTime.DATE_FULL,
);
});
/* Filter out structural tags */
eleventyConfig.addFilter("removeBasicTags", (tags) => {
return tags.filter(tag => ["all", "posts", "gallery", "reference", "tagPagination"].indexOf(tag) === -1);
return tags.filter(
(tag) =>
[
"all",
"posts",
"gallery",
"reference",
"tagPagination",
"blur",
].indexOf(tag) === -1,
);
});
/* What it says */
eleventyConfig.addFilter("sortAlphabetically", strings =>
(strings || []).sort((b, a) => b.localeCompare(a))
/* What it says on the tin */
eleventyConfig.addFilter("sortAlphabetically", (strings) =>
(strings || []).sort((b, a) => b.localeCompare(a)),
);
/* Remove year from image filenames for OG metadata */
/* Remove year from image filenames for OG metadata file path */
eleventyConfig.addFilter("toOgFilename", (filename) => {
return filename.split("/")[1];
})
};
});
}
+24 -3
View File
@@ -1,7 +1,7 @@
<footer>
<ul>
<li>
<a href="/colophon" title="colophon" aria-label="colophon"
<a href="/colophon/"
{% if page.url == "/colophon/" %}aria-current="page"{% endif %}>
colophon
</a>
@@ -9,9 +9,9 @@
<li>
<a href="/" title="go home"
aria-label="go home | {{ metadata.title }} from {{ metadata.author }} in 2026"
aria-label="go home | {{ metadata.title }} from {{ metadata.author }}, copyright 2022-2026"
{% if page.url == "/" %}aria-current="page"{% endif %}>
{{ metadata.title }} from {{ metadata.author }} in 2026</a>
{{ metadata.title }} from {{ metadata.author }}, © 2022-2026</a>
</li>
<li>
@@ -21,4 +21,25 @@
</a>
</li>
</ul>
<fieldset id="theme">
<legend>color scheme</legend>
<input type="radio" id="theme-light" name="theme" value="light"/>
<label class="theme-light" for="theme-light">
<i class="fa-regular fa-sun" aria-hidden="true"></i>
light
</label>
<input type="radio" id="theme-auto" name="theme" value="auto" checked/>
<label class="theme-auto" for="theme-auto">
auto
</label>
<input type="radio" id="theme-dark" name="theme" value="dark"/>
<label class="theme-dark" for="theme-dark">
dark
<i class="fa-regular fa-moon" aria-hidden="true"></i>
</label>
</fieldset>
</footer>
+51
View File
@@ -0,0 +1,51 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" type="image/x-icon" href="/favicon.ico">
{% set pageTitle %}{{ title | safe }} | {{ metadata.title }}{% endset %}
<title>{{ pageTitle }}</title>
<meta name="description" content="{{ description or metadata.description }}">
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
<meta property="og:title" content="{{ pageTitle }}" />
<meta property="og:type" content="website" />
<meta property="og:description" content="{{ description or metadata.description }}" />
<meta property="og:site_name" content="{{ metadata.title }}" />
<meta property="og:url" content="{{ metadata.url }}{{ page.url }}" />
{% if image %}
<meta property="og:image" content="{{ metadata.url }}/img/{{ image.src | toOgFilename }}" />
<meta property="og:image:alt" content="{{ image.alt }}" />
{% else %}
<meta property="og:image" content="{{ metadata.url }}/favicon.ico" />
<meta property="og:image:alt" content="a teal bird icon" />
{% endif %}
<meta name="generator" content="{{ eleventy.generator }}">
<meta itemprop="ai-content-declaration:version" content="1.0.0">
<meta itemprop="ai-content-declaration:level" content="none">
{# Fonts #}
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Atkinson+Hyperlegible+Mono:ital,wght@0,200..800;1,200..800&family=Atkinson+Hyperlegible+Next:ital,wght@0,200..800;1,200..800&display=swap" rel="stylesheet">
{# Icons #}
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
{# Styles #}
<style>{% include "css/main.css" %}</style>
<style>{% include "css/nav.css" %}</style>
<style>{% include "css/pagefind.css" %}</style>
<style>{% include "css/highlighting.css" %}</style>
<style>{% include "css/print.css" %}</style>
<style>{% getBundle "css" %}</style>
{# Scripts #}
<script>{% include "js/theme.js" %}</script>
<script type="module">{% getBundle "js" %}</script>
{# Pagefind #}
<link href="/pagefind/pagefind-component-ui.css" rel="stylesheet">
<script src="/pagefind/pagefind-component-ui.js" type="module"></script>
+8 -4
View File
@@ -1,6 +1,5 @@
<header>
<a href="#main" id="skip" title="skip to main content" aria-label="skip to main content">
<a href="#main" id="skip" title="skip to main content">
<i class="fa-solid fa-forward" aria-hidden="true"></i> skip
</a>
@@ -9,8 +8,7 @@
{% for entry in collections.all | eleventyNavigation %}
<li>
<a href="{{ entry.url }}" title="{{ entry.data.label }}"
{% if entry.url == page.url %}aria-current="page"{% endif %}
aria-label="{{ entry.data.label }}">
{% if entry.url == page.url %}aria-current="page"{% endif %}>
<i class="{{ entry.data.icon }}" aria-hidden="true"></i>
<span class="menu-text">{{ entry.title }}</span>
</a>
@@ -19,4 +17,10 @@
</ul>
</nav>
<div class="dark searchbox" data-pf-theme="dark">
<pagefind-searchbox></pagefind-searchbox>
</div>
<div class="light searchbox">
<pagefind-searchbox></pagefind-searchbox>
</div>
</header>
+7 -41
View File
@@ -1,51 +1,17 @@
<!doctype html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
{% set pageTitle %}{{ title }} | {{ metadata.title }}{% endset %}
<title>{{ pageTitle }}</title>
<meta name="description" content="{{ description or metadata.description }}">
<link rel="alternate" href="/feed.xml" type="application/atom+xml" title="{{ metadata.title }}">
<meta property="og:title" content="{{ title or metadata.title }}" />
<meta property="og:type" content="website" />
<meta property="og:description" content="{{ description or metadata.description }}" />
<meta property="og:site_name" content="{{ metadata.title }}" />
{% if image %}
<meta property="og:image" content="/img/{{ image.src | toOgFilename }}" />
<meta property="og:image:alt" content="{{ image.alt }}" />
{% endif %}
<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">
{# Icons #}
<script src="https://kit.fontawesome.com/884dded219.js" crossorigin="anonymous"></script>
{# Styles #}
<style>{% include "css/main.css" %}</style>
<style>{% include "css/nav.css" %}</style>
<style>{% include "css/print.css" %}</style>
<style>{% getBundle "css" %}</style>
<script type="module">{% getBundle "js" %}</script>
</head>
<body>
<html lang="en">
<head>
{% include "head-content.njk" %}
</head>
<body>
{% include "header.njk" %}
<main id="main">
{{ content | safe }}
<hr>
</main>
{% include "footer.njk" %}
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
<body>
</body>
</html>
+1 -1
View File
@@ -3,7 +3,7 @@ layout: base.njk
---
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
<heading-anchors content="<i class='fa-solid fa-anchor'></i>" data-pagefind-body>
<h1>{{ title }}</h1>
{{ content | safe }}
+13
View File
@@ -0,0 +1,13 @@
---
layout: post.njk
---
{% css %}{% include "css/post-toc.css" %}{% endcss %}
<aside id="toc">
<details>
<summary><h2>table of contents</h2></summary>
{{ content | toc | safe }}
</details>
</aside>
{{ content | safe }}
+21 -3
View File
@@ -2,11 +2,13 @@
layout: base.njk
---
{% css %}{% include "css/post.css" %}{% endcss %}
{% css %}{% include "css/highlighting.css" %}{% endcss %}
{% css %}{% include "css/lists.css" %}{% endcss %}
{% css %}{% include "css/modal.css" %}{% endcss %}
{% js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %}
{% js %}{% include "js/modal.js" %}{% endjs %}
<heading-anchors content="<i class='fa-solid fa-anchor'></i>">
<article>
<article data-pagefind-body>
<h1>{{ title }}</h1>
<div class="post-metadata">
@@ -29,7 +31,11 @@ layout: base.njk
</div>
{% if image %}
<img src="/img/{{ image.src }}" alt="{{ image.alt }}">
<dialog closedby="any" aria-label="image modal" tabindex="-1">
<button class="close-dialog" autofocus aria-label="close the image modal">&times;</button>
<img class="modal-img" src="/img/{{ image.src }}" alt="{{ image.alt }}">
</dialog>
<img class="hero" src="/img/{{ image.src }}" alt="{{ image.alt }}">
{% endif %}
{{ content | safe }}
@@ -43,4 +49,16 @@ layout: base.njk
{% set newerTitle = newerPost.data.title %}
{% set inPost = true %}
{% include "pagination.njk" %}
<hr>
{% set relevantTags = tags | removeBasicTags %}
{% set postlist = collections.posts | filterByTags(relevantTags) | excludeFromCollection([page.url, olderHref, newerHref]) | randomize | head(3) %}
{% if postlist.length %}
<section class="related-posts">
<h2 data-ha-exclude>related posts</h2>
{% include "postlist.njk" %}
</section>
{% endif %}
</heading-anchors>
-6
View File
@@ -1,6 +0,0 @@
---
layout: base.njk
---
{% css %}{% include "css/resume.css" %}{% endcss %}
{{ content | safe }}
+21
View File
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="en">
<head>
{% include "head-content.njk" %}
<meta http-equiv="refresh" content="0; url=/tags/{{ tag }}">
</head>
<body>
{% include "header.njk" %}
<main id="main">
<h1>{{ title }}</h1>
{{ content | safe }}
</main>
{% include "footer.njk" %}
<!-- This page `{{ page.url }}` was built on {% currentBuildDate %} -->
<body>
</html>
+4 -3
View File
@@ -2,15 +2,16 @@
{% for post in postlist %}
<li class="post">
<a class="postlink" href="{{ post.url }}">
<h2 data-ha-exclude>{{ post.data.title }} {% if "blur" in post.data.tags %}(mature){% endif %}</h2>
{% if post.data.image %}
<img src="/img/{{ post.data.image.src }}" alt="{{ post.data.image.alt }}">
{% endif %}
<h2>{{ post.data.title }}</h2>
<ul class="postlist-tags">
{% for tag in post.data.tags | removeBasicTags %}
<li>{{ tag }}</li>
{% endfor %}
</ul>
<img src="/img/{{ post.data.image.src }}" alt="{{ post.data.image.alt }}"
{% if "blur" in post.data.tags %}class="blur"{% endif %}>
{% endif %}
</a>
</li>
{% endfor %}
+30
View File
@@ -0,0 +1,30 @@
main {
margin-bottom: 2rem;
}
.rss-explainer {
background: var(--color-bg-alt);
padding: 1rem;
margin-block: 1rem;
border-radius: .5rem;
}
.rss-explainer p {
margin: 0;
}
.rss-explainer p + p {
margin-top: 1.25rem;
}
.feed-url {
font-family: var(--font-family-code);
font-size: .9rem;
text-align: center;
}
p:has(small) {
display: block;
margin: .25rem 0 0 .75rem;
color: var(--color-grey);
}
+1 -1
View File
@@ -7,7 +7,7 @@ code[class*=language-],
pre[class*=language-] {
font-family: var(--font-family-code);
background-color: var(--color-bg-alt);
font-size: .9rem;
font-size: .9em;
text-shadow: 0 1px var(--color-shadow);
-moz-tab-size: 4;
-o-tab-size: 4;
+7 -3
View File
@@ -93,7 +93,6 @@
/* Click animation */
.postlink:active,
.taglink:active {
box-shadow: none;
top: .2rem;
left: .2rem;
box-shadow: .15rem .15rem var(--color-shadow);
@@ -112,6 +111,7 @@
grid-area: h2;
padding: .25rem .5rem;
text-transform: uppercase;
font-family: var(--font-family);
font-size: 1.5rem;
color: var(--color-primary);
border-radius: 1rem 1rem 0 0;
@@ -143,6 +143,11 @@
grid-area: img;
}
.blur {
filter: blur(.75rem);
clip-path: inset(0 round 1rem);
}
.tag-imgs {
display: grid;
grid-template-columns: repeat(2, 1fr);
@@ -158,7 +163,7 @@
width: 100%;
aspect-ratio: 3 / 2;
background-color: var(--color-bg-alt);
border-radius: calc(1rem);
border-radius: 1rem;
}
.taglink:focus-visible .missing-image {
@@ -216,4 +221,3 @@
.tag:nth-child(odd) p {
text-align: right;
}
+49 -20
View File
@@ -1,7 +1,17 @@
@font-face {
font-family: "Peritel";
src:
url("/fonts/Peritel/Peritel-Regular.woff2") format("woff2"),
url("/fonts/Peritel/Peritel-Regular.otf") format("opentype");
}
:root {
color-scheme: light dark;
--font-family: 'Atkinson Hyperlegible Next', sans-serif;
/* if you change the header font, go to post-toc.css and fuck about with the width
of the table of contents */
--font-family-headers: 'Peritel', 'Atkinson Hyperlegible Next', sans-serif;
--font-family-code: 'Atkinson Hyperlegible Mono', monospace;
--color-dark: #2e303e;
@@ -17,7 +27,7 @@
--color-shadow: rgba(2, 10, 40, .25);
/* Used for syntax highlighting */
--color-red-light: #e95678;
--color-red-light: #f195aa;
--color-orange-light: #fab795;
--color-yellow-light: #fbe6bc;
--color-green-light: #29d398;
@@ -49,12 +59,16 @@
--color-blue: light-dark(var(--color-blue-dark), var(--color-blue-light));
--color-purple: light-dark(var(--color-purple-dark), var(--color-purple-light));
--color-grey: light-dark(var(--color-grey-dark), var(--color-grey-light));
}
--header-offset: 3.1rem;
:root:has(#theme-light:checked) {
color-scheme: light;
}
:root:has(#theme-dark:checked) {
color-scheme: dark;
}
/* Base */
* {
box-sizing: border-box;
margin: 0;
@@ -71,10 +85,9 @@ main {
width: 60vw;
max-width: 1000px;
margin: 0 auto;
scroll-margin-top: var(--header-offset);
}
@media (max-width: 1050px) {
@media (max-width: 1100px) {
main {
width: 75vw;
}
@@ -90,34 +103,38 @@ main {
h1, h2, h3, h4, h5, h6 {
line-height: 1.25;
color: var(--color-teal);
scroll-margin-top: var(--header-offset);
font-family: var(--font-family-headers);
letter-spacing: 0.1rem;
}
h1 {
margin-top: 3rem;
font-size: 3.5rem;
font-size: 3.7rem;
text-align: center;
}
h2 {
margin-top: 2rem;
font-size: 2.2rem;
font-size: 2.35rem;
}
h3 {
margin-top: 1.5rem;
font-size: 1.6rem;
font-size: 1.7rem;
}
@media (max-width: 650px) {
h1 { font-size: 2.8rem; }
h1 {
margin-top: 1.5rem;
font-size: 2.25rem;
}
h2 { font-size: 1.8rem; }
h3 { font-size: 1.35rem; }
h3 { font-size: 1.4rem; }
}
h4, h5, h6 {
margin-top: 1rem;
font-size: 1.2rem;
font-size: 1.25rem;
}
/* Images */
@@ -126,6 +143,7 @@ img {
max-width: 100%;
height: auto;
border-radius: 1rem;
margin: 0 auto;
}
/* Paragraphs */
@@ -169,12 +187,13 @@ a:active {
a.ha,
span.ha-placeholder {
color: var(--color-pink);
font-size: .8em;
vertical-align: .1em;
}
span.ha-placeholder {
opacity: .55;
}
/* Lists */
::marker {
color: var(--color-pink);
@@ -184,14 +203,27 @@ ul, ol, dl, li {
margin-left: 1rem;
}
@media (max-width: 650px) {
ul, ol, dl {
margin-left: 0;
}
}
li {
line-height: 1.2 5;
line-height: 1.4;
margin-top: .65rem;
margin-bottom: .65rem;
}
li ul, li ol {
margin: .5rem 0;
margin-left: 1rem;
}
@media (max-width: 650px) {
li ul, li ol {
margin-left: 0;
}
}
dt {
@@ -208,7 +240,7 @@ dd {
blockquote {
margin: .5rem 0;
padding: 0 1rem;
border-radius: .25rem 1rem 1rem .25rem;
border-radius: .5rem;
line-height: 1.25;
border-left: .5rem solid var(--color-pink);
}
@@ -231,6 +263,7 @@ table {
border-spacing: 0; /* border collapse doesn't play nice with radii */
border-radius: .3rem;
border: thin solid var(--color-pink);
margin: 1.25rem 0;
}
th {
@@ -260,13 +293,9 @@ time {
/* Horizontal rules */
hr {
color: var(--color-teal);
border: .25rem solid var(--color-teal);
border: .25rem solid var(--color-pink);
margin: 2rem 0;
}
hr:last-child {
margin-bottom: 0;
}
/* Used on home, reference, gallery pages */
.centered {
+89
View File
@@ -0,0 +1,89 @@
img[tabindex="0"] {
cursor: pointer;
}
img[tabindex="0"]:focus-visible {
outline: .15rem solid var(--color-teal);
}
dialog {
margin: auto;
flex-flow: column;
background: transparent;
border: none;
position: absolute;
}
dialog[open] {
display: flex;
}
dialog::backdrop {
background-color: rgba(from var(--color-bg) r g b / .8);
backdrop-filter: blur(4px);
}
body:has(dialog[open]) {
overflow: hidden;
}
.close-dialog {
background-color: rgba(from var(--color-teal) r g b / .35);
font-size: 1.5rem;
padding: 0 .5rem .15rem;
border-radius: 1rem;
color: var(--color-teal);
box-shadow: .15rem .15rem var(--color-shadow);
border: .08rem solid var(--color-teal);
align-self: flex-end;
justify-self: flex-start;
margin: 0 .1rem;
/* Click animation handling */
position: relative;
top: 1rem;
left: -.15rem;
transition: top .1s ease-in, left .1s ease-in;
}
.close-dialog:focus-visible {
outline: none;
background-color: var(--color-teal);
color: var(--color-bg);
}
@media (any-hover: hover) {
.close-dialog:hover {
outline: none;
background-color: var(--color-teal);
color: var(--color-bg);
}
}
@media (forced-colors: active) {
.close-dialog:focus-visible {
outline-offset: .08rem;
outline: .08rem solid;
}
@media (any-hover: hover) {
.close-dialog:hover {
outline-offset: .08rem;
outline: .08rem solid;
}
}
}
/* Click animation */
.close-dialog:active {
top: 1.1rem;
left: -.05rem;
box-shadow: .05rem .05rem var(--color-shadow);
}
.modal-img {
max-height: calc(100vh - 2rem);
object-fit: contain;
width: auto;
max-width: 90%;
margin: 0 auto;
}
+114 -7
View File
@@ -1,11 +1,11 @@
/* Header */
header {
position: sticky;
top: 0;
background-color: var(--color-bg);
box-shadow: 0 .25rem .15rem var(--color-shadow);
padding: .75rem 0;
z-index: 10;
border-bottom: thick solid var(--color-teal);
box-shadow: 0 .25rem .15rem var(--color-shadow);
display: grid;
grid-template-columns: auto;
}
/* Header links, pagination links */
@@ -163,7 +163,7 @@ a[aria-current="page"] a:focus-visible i,
width: auto;
height: auto;
overflow: auto;
margin: 0 10%;
margin: -.125rem 10%;
z-index: 999;
}
@@ -198,6 +198,8 @@ header li {
footer {
padding: 1rem 0;
font-size: .9rem;
border-top: thick solid var(--color-pink);
margin-top: 2rem;
}
footer ul {
@@ -238,6 +240,111 @@ footer a:focus-visible {
outline-color: var(--color-pink);
}
/* color picker */
#theme {
display: flex;
justify-content: center;
margin: .5rem auto 0;
padding: 0 .75rem .5rem;
width: fit-content;
border: .125rem solid var(--color-teal);
border-radius: 2rem;
}
#theme legend {
margin: 0 auto;
color: var(--color-teal);
}
footer label {
cursor: pointer;
border: .125rem solid var(--color-pink);
padding: 0 .25rem;
color: var(--color-pink);
background-color: var(--color-bg); /* this stops the box shadows from showing through */
box-shadow: .15em .15em var(--color-shadow);
/* Click animation handling */
position: relative;
top: 0;
left: 0;
transition: top .05s ease-in, left .05s ease-in;
}
footer input:checked + label {
color: var(--color-blue);
border-color: var(--color-blue);
}
footer label i {
color: var(--color-teal);
}
footer input:checked + label i {
color: var(--color-pink);
}
@media (any-hover: hover) {
footer label:hover,
footer input:checked + label:hover,
footer label:hover i,
footer input:checked + label:hover i {
color: var(--color-bg);
}
footer label:hover {
background-color: var(--color-pink);
}
footer input:checked + label:hover {
background-color: var(--color-teal);
}
}
footer input:focus-visible + label,
footer input:focus-visible + label i {
color: var(--color-bg);
background-color: var(--color-pink);
border-color: var(--color-pink);
}
footer input:checked:focus-visible + label,
footer input:checked:focus-visible + label i {
color: var(--color-bg);
background-color: var(--color-teal);
border-color: var(--color-teal);
}
footer label:active {
top: .09em;
left: .09em;
box-shadow: .05em .05em var(--color-shadow);
}
label.theme-light {
border-top-left-radius: 1rem;
border-bottom-left-radius: 1rem;
border-right: none;
padding-left: .35rem;
}
label.theme-auto {
}
label.theme-dark {
border-top-right-radius: 1rem;
border-bottom-right-radius: 1rem;
border-left: none;
padding-right: .35rem;
}
footer input {
/* To allow screen reader to still access these. */
/* From https://lyra.horse/blog/2025/08/you-dont-need-js/ */
opacity: 0;
position: absolute;
pointer-events: none;
}
/* Pagination */
.pagination,
.pagination li {
@@ -280,8 +387,8 @@ footer a:focus-visible {
display: flex;
flex-flow: row wrap;
list-style: none;
justify-content: space-around;
gap: .35rem;
justify-content: center;
gap: .5rem;
}
.webring ul,
+106
View File
@@ -0,0 +1,106 @@
/* Handle color schemes */
:root:has(#theme-light:checked) .dark {
display: none;
}
:root:has(#theme-dark:checked) .light {
display: none;
}
@media (prefers-color-scheme: light) {
:root:not(:has(#theme-dark:checked)) .dark {
display: none;
}
}
@media (prefers-color-scheme: dark) {
:root:not(:has(#theme-light:checked)) .light {
display: none;
}
}
.searchbox {
margin: 1rem auto 0;
}
pagefind-searchbox {
/* Shadows */
--pf-scroll-shadow: var(--color-shadow) !important;
--pf-shadow-sm: .15rem .15rem 0 var(--color-shadow) !important;
--pf-shadow-md: .25rem .25rem 0 var(--color-shadow) !important;
--pf-shadow-lg: 1rem 1rem 0 var(--color-shadow) !important;
/* Typography */
--pf-font: var(--font-family) !important;
/* Border */
--pf-border-radius: 1.5rem !important;
/* Focus */
--pf-outline-width: .125rem !important;
--pf-outline-offset: 0 !important;
/* Width */
--pf-searchbox-max-width: min(550px, 92vw) !important;
}
.light pagefind-searchbox {
--pf-text: var(--color-dark) !important;
--pf-text-secondary: var(--color-dark-alt) !important;
--pf-text-muted: var(--color-dark-alt) !important;
--pf-background: var(--color-light-alt) !important;
--pf-border: var(--color-pink-dark) !important;
--pf-border-focus: var(--color-pink-dark) !important;
--pf-skeleton: var(--color-light) !important;
--pf-skeleton-shine: var(--color-dark) !important;
--pf-hover: var(--color-light) !important;
--pf-mark: var(--color-teal-dark) !important;
--pf-outline-focus: var(--color-teal-dark) !important;
/* Error */
--pf-error-bg: var(--color-light-alt) !important;
--pf-error-border: var(--color-red-dark) !important;
--pf-error-text: var(--color-red-dark) !important;
--pf-error-text-secondary: var(--color-red-dark) !important;
}
.dark pagefind-searchbox {
--pf-text: var(--color-light) !important;
--pf-text-secondary: var(--color-light-alt) !important;
--pf-text-muted: var(--color-light-alt) !important;
--pf-background: var(--color-dark-alt) !important;
--pf-border: var(--color-pink-light) !important;
--pf-border-focus: var(--color-pink-light) !important;
--pf-skeleton: var(--color-dark) !important;
--pf-skeleton-shine: var(--color-dark) !important;
--pf-hover: var(--color-dark) !important;
--pf-mark: var(--color-teal-light) !important;
--pf-outline-focus: var(--color-teal-light) !important;
/* Error */
--pf-error-bg: var(--color-dark-alt) !important;
--pf-error-border: var(--color-red-light) !important;
--pf-error-text: var(--color-red-light) !important;
--pf-error-text-secondary: var(--color-red-light) !important;
}
pagefind-searchbox input {
border-width: .125rem !important;
}
pagefind-searchbox input:not(:focus-visible) {
box-shadow: var(--pf-shadow-md) !important;
}
@media (max-width: 650px) {
.pf-trigger-shortcut {
display: none !important;
}
}
.pf-searchbox-dropdown,
.pf-searchbox-footer {
border-width: .125rem !important;
}
.pf-error {
margin-top: .5rem !important;
}
+103
View File
@@ -0,0 +1,103 @@
#toc {
float: right;
margin: 1rem 0 1.5rem 1.5rem;
width: fit-content;
max-width: 55%;
}
@media (max-width: 900px) {
#toc {
float: unset;
margin-top: 2rem;
margin-left: .5rem;
width: calc(100% - .5rem);
max-width: unset;
}
}
#toc details {
border: thick solid var(--color-pink);
border-radius: 1rem;
margin-top: 1rem;
background-color: var(--color-bg);
}
#toc summary {
position: relative;
top: -1.5rem;
left: -.75rem;
width: fit-content;
background: var(--color-bg);
border-radius: .5rem;
cursor: pointer;
padding-inline-end: .25rem;
}
#toc summary:focus-visible {
outline: .15rem solid var(--color-teal);
}
#toc summary::marker {
font-size: 2.35rem;
}
#toc h2 {
margin-top: 0;
display: inline;
line-height: normal;
}
#toc nav {
position: relative;
top: -1.25rem;
}
/* `tree` style toc */
#toc nav > ol {
margin-inline: 1rem;
}
#toc ol {
margin: 0;
}
#toc li {
position: relative;
padding-inline-start: 1em;
list-style: none;
margin-block: 0;
margin-left: .35rem;
}
#toc li::before,
#toc li::after {
display: block;
position: absolute;
box-sizing: border-box;
inset-block: 0 auto;
inset-inline: 0 auto;
inline-size: .75em;
border-inline-start: .1rem solid var(--color-pink);
}
#toc li::before {
block-size: .5lh;
border-block-end: .1rem solid var(--color-pink);
content: "";
}
#toc li:not(:last-child)::after {
block-size: 100%;
content: "";
}
/* underlines are unnecessary in this context */
#toc a {
text-decoration: none;
color: var(--color-blue);
font-weight: bold;
}
#toc a:focus-visible {
outline-color: var(--color-pink);
}
+1 -1
View File
@@ -17,6 +17,7 @@
gap: .5rem;
list-style: none;
margin: 0;
margin-left: auto;
}
.post-tags li {
@@ -72,4 +73,3 @@
left: .1rem;
box-shadow: .05rem .05rem var(--color-shadow);
}
+16
View File
@@ -34,8 +34,24 @@
.job-details a {
font-size: 1rem;
font-family: var(--font-family);
}
.job p {
margin-top: 0;
}
.job li strong:not(a) {
color: var(--color-teal);
}
.testimonial {
font-style: italic;
text-align: right;
color: var(--color-teal);
/* reset some of the default bq styling */
border-left: none;
border-radius: 0;
background-color: transparent;
margin-top: 0;
}
+64 -7
View File
@@ -1,11 +1,18 @@
import { IdAttributePlugin } from "@11ty/eleventy";
import { HtmlBasePlugin } from "@11ty/eleventy";
import { eleventyImageTransformPlugin } from "@11ty/eleventy-img";
import eleventyNavigationPlugin from "@11ty/eleventy-navigation";
import { feedPlugin } from "@11ty/eleventy-plugin-rss";
import syntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight";
import toc from "eleventy-plugin-nesting-toc";
import { attrs } from "@mdit/plugin-attrs";
import { chunk } from "lodash-es";
import { markdownitLinkAttributes } from 'markdown-it-link-attributes';
import markdownitIdAttributes from "markdown-it-anchor";
import path from "node:path";
import { execSync } from 'child_process';
import { chunk } from "lodash-es";
import pluginFilters from "./_config/filters.js";
@@ -13,6 +20,23 @@ export default async function(eleventyConfig) {
/* Markdown HTML attribute parsing */
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(attrs));
/* Markdown apply target="_blank" to all external links */
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitLinkAttributes, {
matcher(href) {
return href.match(/^https?:\/\//);
},
attrs: {
target: "_blank",
rel: "external",
},
}));
/* Markdown apply ID attributes to headers */
eleventyConfig.amendLibrary("md", (mdLib) => mdLib.use(markdownitIdAttributes, {
level: [2, 3, 4],
tabIndex: false,
}));
/* Bundles */
/* CSS */
eleventyConfig.addBundle("css", {
@@ -30,7 +54,7 @@ export default async function(eleventyConfig) {
/* Tag pagination */
eleventyConfig.addCollection("tagPagination", function(collection) {
let tagSet = new Set(collection.getAllSorted().flatMap((post) => post.data.tags || []));
tagSet = tagSet.difference(new Set(["posts", "gallery", "reference"]));
tagSet = tagSet.difference(new Set(["posts", "gallery", "reference", "blur"]));
let paginationSize = 13;
let tagMap = [];
@@ -53,6 +77,12 @@ export default async function(eleventyConfig) {
return tagMap;
});
/* Passthrough */
eleventyConfig
.addPassthroughCopy("favicon.ico")
.addPassthroughCopy("fonts")
.addPassthroughCopy("robots.txt");
/* Plugins */
/* All filters from _config/filters.js */
eleventyConfig.addPlugin(pluginFilters);
@@ -61,6 +91,7 @@ export default async function(eleventyConfig) {
eleventyConfig.addPlugin(feedPlugin, {
type: "atom", // or "rss", "json"
outputPath: "/feed.xml",
stylesheet: "/feed.xsl",
collection: {
name: "posts", // iterate over `collections.posts`
limit: 10, // 0 means no limit
@@ -77,6 +108,9 @@ export default async function(eleventyConfig) {
}
});
/* HTML base */
eleventyConfig.addPlugin(HtmlBasePlugin);
/* Images */
eleventyConfig.addPlugin(eleventyImageTransformPlugin, {
// output image formats
@@ -92,7 +126,12 @@ export default async function(eleventyConfig) {
decoding: "async",
},
},
filenameFormat: function (id, src, width, format, options) {
filenameFormat: function (hash, src, width, format, options) {
// If you're building multiple widths
// const extension = path.extname(src);
// const name = path.basename(src, extension);
// return `${name}-${width}.${extension}`;
return path.basename(src);
},
});
@@ -100,12 +139,23 @@ export default async function(eleventyConfig) {
/* Navigation */
eleventyConfig.addPlugin(eleventyNavigationPlugin);
/* `id` attributes */
eleventyConfig.addPlugin(IdAttributePlugin);
/* Syntax highlighting */
eleventyConfig.addPlugin(syntaxHighlight);
/* Table of contents */
eleventyConfig.addPlugin(toc);
/* Draft handling */
eleventyConfig.addPreprocessor("drafts", "*", (data, content) => {
if (data.draft) {
data.title = `${data.title} (draft)`;
}
if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") {
return false;
}
});
/* Shortcodes */
eleventyConfig.addShortcode("currentBuildDate", () => {
return (new Date()).toISOString();
@@ -113,6 +163,13 @@ export default async function(eleventyConfig) {
/* Watch when serving */
eleventyConfig.addWatchTarget("css");
eleventyConfig.addWatchTarget("js");
/* Implement search */
/* From https://rknight.me/blog/using-pagefind-with-eleventy-for-search/ */
eleventyConfig.on('eleventy.after', () => {
execSync(`npx pagefind --site _site --glob \"**/*.html\"`, { encoding: 'utf-8' })
});
};
export const config = {
Executable
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+33
View File
@@ -0,0 +1,33 @@
# End User License Agreement (EULA)
This End User License Agreement is a legal agreement between the licensee (you), and the author of this font, Christopher Kirk-Nielsen.
You are granted a perpetual, non-exclusive license to use the font with your purchase.
## By downloading or purchasing this font, you agree to the following terms:
**For use on a website**
Use on any website owned or under the licensee's control, no pageview limits.
**For use in an app**
App embed allowed for 1 app. Another app = another license.
**Distribution**
The font may not be redistributed.
**Personal modification**
The font may be modified for personal use, but cannot be redistributed.
**Do not use the font for hateful purposes**
The font is not allowed to be used in any material promoting hate speech of any kind, including but not limited to: racism, xenophobia, homophobia, sexism, or other types of discrimination.
**Do not use the font with AI**
The font is not allowed to be used in, or in training of, AI/LLMs.
**Use at your own risk**
Any usage of the fonts are at the licensee's own risk.
For ebooks and other commercial use, or any other specific needs, email me to figure something out: chriskirknielsen+fonts[at]gmail.com
Thank you very much for the support!
Christopher Kirk-Nielsen (https://chriskirknielsen.com/fonts/)
Binary file not shown.
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
/* don't even bother on mobile */
if (window.innerWidth > 650) {
const dialog = document.querySelector("dialog");
const closeButton = document.querySelector(".close-dialog");
const hero = document.querySelector(".hero");
hero.tabIndex = 0;
hero.addEventListener("click", (e) => dialog.showModal());
hero.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
dialog.showModal();
}
});
closeButton.addEventListener("click", (e) => dialog.close());
closeButton.addEventListener("keydown", (e) => {
if (e.key === "Enter" || e.key === " ") {
e.preventDefault();
dialog.close();
}
});
}
+35
View File
@@ -0,0 +1,35 @@
const THEME = "theme";
const saveTheme = (themeValue) => {
localStorage.setItem(THEME, themeValue);
};
const themeLight = document.getElementById("theme-light");
themeLight.addEventListener("input", (e) => {
saveTheme(themeLight.value);
});
const themeAuto = document.getElementById("theme-auto");
themeAuto.addEventListener("input", (e) => {
saveTheme(themeAuto.auto);
});
const themeDark = document.getElementById("theme-dark");
themeDark.addEventListener("input", (e) => {
saveTheme(themeDark.value);
});
var currentThemeValue = localStorage.getItem(THEME);
switch (currentThemeValue) {
case "light":
themeLight.checked = true;
themeAuto.checked = false;
break;
case "dark":
themeDark.checked = true;
themeAuto.checked = false;
break;
case "auto":
default:
themeAuto.checked = true;
}
+1
Submodule leecat.art-site added at 7e4d8c1a97.
Executable
+37
View File
@@ -0,0 +1,37 @@
#!/bin/bash
# check for mogrify
which mogrify > /dev/null
if [[ $? -ne 0 ]]
then
echo "mogrify not found, run the following:"
echo "sudo apt install imagemagick"
exit 1
fi
# finds pattern [number]x[number]
REGEX="([0-9]+)x[0-9]+"
MAX_WIDTH=1200
for FILE in $(find src/img)
do
# skip directories
if [ -d $FILE ]
then
continue
fi
# `identify` prints out file info incl. dimensions in pixels
if [[ $(identify $FILE) =~ $REGEX ]]
then
# regex capture groups
WIDTH=${BASH_REMATCH[1]}
# resize if too large
if (( $WIDTH > $MAX_WIDTH ))
then
echo "resizing $FILE with width $WIDTH"
mogrify -resize 1200x $FILE
fi
fi
done
+714 -143
View File
File diff suppressed because it is too large. Load diff
+7 -3
View File
@@ -2,10 +2,9 @@
"name": "leecat.art",
"version": "1.0.0",
"description": "Lee's personal website, take 2, built with 11ty",
"main": "index.js",
"scripts": {
"build": "rm -rf _site && npx @11ty/eleventy --quiet",
"start": "rm -rf _site && npx @11ty/eleventy --serve --quiet"
"dev": "rm -rf _site && npx @11ty/eleventy --serve --quiet --output _site"
},
"keywords": [],
"author": "Lee Cattarin",
@@ -20,7 +19,12 @@
"@11ty/eleventy-plugin-syntaxhighlight": "^5.0.2",
"@mdit/plugin-attrs": "^0.24.2",
"@zachleat/heading-anchors": "https://github.com/lee0c/heading-anchors/tarball/main",
"cheerio": "^1.2.0",
"eleventy-plugin-nesting-toc": "^1.3.0",
"lodash-es": "^4.17.23",
"luxon": "^3.7.2"
"luxon": "^3.7.2",
"markdown-it-anchor": "^10.0.0",
"markdown-it-link-attributes": "https://github.com/lee0c/markdown-it-link-attributes/tarball/main",
"pagefind": "^1.5.2"
}
}
+151
View File
@@ -0,0 +1,151 @@
# Sourced from https://codeberg.org/superseriousbusiness/gotosocial/
# AI scrapers and the like.
# https://github.com/ai-robots-txt/ai.robots.txt/
User-agent: AddSearchBot
User-agent: AI2Bot
User-agent: AI2Bot-DeepResearchEval
User-agent: Ai2Bot-Dolma
User-agent: aiHitBot
User-agent: amazon-kendra
User-agent: Amazonbot
User-agent: AmazonBuyForMe
User-agent: Andibot
User-agent: Anomura
User-agent: anthropic-ai
User-agent: Applebot
User-agent: Applebot-Extended
User-agent: atlassian-bot
User-agent: Awario
User-agent: bedrockbot
User-agent: bigsur.ai
User-agent: Bravebot
User-agent: Brightbot 1.0
User-agent: BuddyBot
User-agent: Bytespider
User-agent: CCBot
User-agent: Channel3Bot
User-agent: ChatGLM-Spider
User-agent: ChatGPT Agent
User-agent: ChatGPT-User
User-agent: Claude-SearchBot
User-agent: Claude-User
User-agent: Claude-Web
User-agent: ClaudeBot
User-agent: Cloudflare-AutoRAG
User-agent: CloudVertexBot
User-agent: cohere-ai
User-agent: cohere-training-data-crawler
User-agent: Cotoyogi
User-agent: Crawl4AI
User-agent: Crawlspace
User-agent: Datenbank Crawler
User-agent: DeepSeekBot
User-agent: Devin
User-agent: Diffbot
User-agent: DuckAssistBot
User-agent: Echobot Bot
User-agent: EchoboxBot
User-agent: FacebookBot
User-agent: facebookexternalhit
User-agent: Factset_spyderbot
User-agent: FirecrawlAgent
User-agent: FriendlyCrawler
User-agent: Gemini-Deep-Research
User-agent: Google-CloudVertexBot
User-agent: Google-Extended
User-agent: Google-Firebase
User-agent: Google-NotebookLM
User-agent: GoogleAgent-Mariner
User-agent: GoogleOther
User-agent: GoogleOther-Image
User-agent: GoogleOther-Video
User-agent: GPTBot
User-agent: iAskBot
User-agent: iaskspider
User-agent: iaskspider/2.0
User-agent: IbouBot
User-agent: ICC-Crawler
User-agent: ImagesiftBot
User-agent: imageSpider
User-agent: img2dataset
User-agent: ISSCyberRiskCrawler
User-agent: Kangaroo Bot
User-agent: KlaviyoAIBot
User-agent: KunatoCrawler
User-agent: laion-huggingface-processor
User-agent: LAIONDownloader
User-agent: LCC
User-agent: LinerBot
User-agent: Linguee Bot
User-agent: LinkupBot
User-agent: Manus-User
User-agent: meta-externalagent
User-agent: Meta-ExternalAgent
User-agent: meta-externalfetcher
User-agent: Meta-ExternalFetcher
User-agent: meta-webindexer
User-agent: MistralAI-User
User-agent: MistralAI-User/1.0
User-agent: MyCentralAIScraperBot
User-agent: netEstate Imprint Crawler
User-agent: NotebookLM
User-agent: NovaAct
User-agent: OAI-SearchBot
User-agent: omgili
User-agent: omgilibot
User-agent: OpenAI
User-agent: Operator
User-agent: PanguBot
User-agent: Panscient
User-agent: panscient.com
User-agent: Perplexity-User
User-agent: PerplexityBot
User-agent: PetalBot
User-agent: PhindBot
User-agent: Poggio-Citations
User-agent: Poseidon Research Crawler
User-agent: QualifiedBot
User-agent: QuillBot
User-agent: quillbot.com
User-agent: SBIntuitionsBot
User-agent: Scrapy
User-agent: SemrushBot-OCOB
User-agent: SemrushBot-SWA
User-agent: ShapBot
User-agent: Sidetrade indexer bot
User-agent: Spider
User-agent: TerraCotta
User-agent: Thinkbot
User-agent: TikTokSpider
User-agent: Timpibot
User-agent: TwinAgent
User-agent: VelenPublicWebCrawler
User-agent: WARDBot
User-agent: Webzio-Extended
User-agent: webzio-extended
User-agent: wpbot
User-agent: WRTNBot
User-agent: YaK
User-agent: YandexAdditional
User-agent: YandexAdditionalBot
User-agent: YouBot
User-agent: ZanistaBot
Disallow: /
# Marketing/SEO "intelligence" data scrapers
User-agent: AwarioRssBot
User-agent: AwarioSmartBot
User-agent: DataForSeoBot
User-agent: magpie-crawler
User-agent: Meltwater
User-agent: peer39_crawler
User-agent: peer39_crawler/1.0
User-agent: PiplBot
User-agent: scoop.it
User-agent: Seekr
Disallow: /
# Rules for everything else
User-agent: *
Crawl-delay: 500
+1 -1
View File
@@ -13,7 +13,7 @@ icon: fa-regular fa-images
label: view the gallery
---
<p class="centered">the gallery page is for finished art</p>
<p class="centered">the gallery section is for finished art</p>
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
{% include "postlist.njk" %}
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 556 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 341 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 565 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 203 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

+3 -1
View File
@@ -10,8 +10,10 @@ eleventyNavigation:
order: 3
icon: fa fa-solid fa-crow
title: home
label: home
---
<p class="centered">(or <a href="/tags/">browse by tags</a>)</p>
<p class="centered">(see the <a href="/tags/highlight/">highlights</a>
or <a href="/tags/">browse by tags</a>)</p>
{% include "postlist.njk" %}
+93
View File
@@ -0,0 +1,93 @@
---
permalink: feed.xsl
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<!--
# Pretty Atom Feed
Based on "Pretty RSS Feed": https://github.com/genmon/aboutfeeds/issues/26
Styles an Atom feed, making it friendly for humans viewers, and adds a link
to aboutfeeds.com for new user onboarding. See it in action:
https://nicolas-hoizey.com/feeds/all.xml
-->
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
<xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<title>feed | <xsl:value-of select="atom:feed/atom:title"/></title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>{% include "css/main.css" %}</style>
<style>{% include "css/feed.css" %}</style>
</head>
<body>
<main>
<div class="rss-explainer">
<p>
<strong>This is a web feed,</strong> also known as an RSS or Atom feed. <strong>Subscribe</strong>
by copying the URL below or from the address bar into your newsreader.
</p>
<p class="feed-url">https://leecat.art/feed.xml</p>
<p>
Visit <a href="https://aboutfeeds.com">About Feeds</a> to get started with newsreaders and subscribing. It’s free.
</p>
</div>
<h1>
<!-- https://commons.wikimedia.org/wiki/File:Feed-icon.svg -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" style="vertical-align: text-bottom; width: 1.2em; height: 1.2em;" id="RSSicon" viewBox="0 0 256 256" role="presentation">
<defs>
<linearGradient x1="0.085" y1="0.085" x2="0.915" y2="0.915" id="RSSg">
<stop offset="0.0" stop-color="#E3702D"/><stop offset="0.1071" stop-color="#EA7D31"/>
<stop offset="0.3503" stop-color="#F69537"/><stop offset="0.5" stop-color="#FB9E3A"/>
<stop offset="0.7016" stop-color="#EA7C31"/><stop offset="0.8866" stop-color="#DE642B"/>
<stop offset="1.0" stop-color="#D95B29"/>
</linearGradient>
</defs>
<rect width="256" height="256" rx="55" ry="55" x="0" y="0" fill="#CC5D15"/>
<rect width="246" height="246" rx="50" ry="50" x="5" y="5" fill="#F49C52"/>
<rect width="236" height="236" rx="47" ry="47" x="10" y="10" fill="url(#RSSg)"/>
<circle cx="68" cy="189" r="24" fill="#FFF"/>
<path d="M160 213h-34a82 82 0 0 0 -82 -82v-34a116 116 0 0 1 116 116z" fill="#FFF"/>
<path d="M184 213A140 140 0 0 0 44 73 V 38a175 175 0 0 1 175 175z" fill="#FFF"/>
</svg>
feed preview: <xsl:value-of select="atom:feed/atom:title"/>
</h1>
<p><xsl:value-of select="atom:feed/atom:description"/></p>
<p>This preview only shows titles, but the actual feed contains the full content.</p>
<p><a>
<xsl:attribute name="href">
<xsl:value-of select="/atom:feed/atom:link[not(@rel)]/@href"/>
</xsl:attribute>
Visit website &#x2192;
</a></p>
<h2>recent items</h2>
<xsl:apply-templates select="atom:feed/atom:entry" />
</main>
</body>
</html>
</xsl:template>
<xsl:template match="atom:feed/atom:entry">
<div>
<h3>
<a>
<xsl:attribute name="href">
<xsl:value-of select="atom:link/@href"/>
</xsl:attribute>
<xsl:value-of select="atom:title"/>
</a>
</h3>
<p><small>
Published: <xsl:value-of select="atom:updated" />
</small></p>
</div>
</xsl:template>
</xsl:stylesheet>
+1
View File
@@ -3,6 +3,7 @@ permalink: sitemap.xml
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="sitemap.xsl" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xhtml="http://www.w3.org/1999/xhtml">
{% for page in collections.all %}
{% if page.data.permalink != false %}
+44
View File
@@ -0,0 +1,44 @@
---
permalink: sitemap.xsl
eleventyExcludeFromCollections: true
---
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9">
<xsl:template match="/">
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>sitemap | hello hello</title>
<style>{% include "css/main.css" %}</style>
</head>
<body>
<main>
<h1>sitemap: hello hello</h1>
<p class="centered">
Return <a href="/">home</a>.
</p>
<table>
<thead>
<tr>
<th>URL</th>
<th>Last modified</th>
</tr>
</thead>
<tbody>
<xsl:for-each select="sitemap:urlset/sitemap:url">
<tr>
<td>
<xsl:value-of select="sitemap:loc" />
</td>
<td>
<xsl:value-of select="sitemap:lastmod" />
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</main>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
+2
View File
@@ -9,6 +9,8 @@ eleventyComputed:
title: "tag: {{ tag.tagName }}"
---
<p class="centered">(or <a href="/tags/">view all tags</a>)</p>
{% set postlist = tag.pageData %}
{% include "postlist.njk" %}
+13
View File
@@ -0,0 +1,13 @@
---
layout: tag-redirect.njk
pagination:
data: collections
size: 1
alias: tag
eleventyComputed:
permalink: /tag/{{ tag | slugify }}/
title: "this page has moved!"
eleventyExcludeFromCollections: true
---
If you're not automatically redirected, head to [the new URL for this tag](/tags/{{ tag | slugify }}/).
+1 -1
View File
@@ -9,7 +9,7 @@ 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>
<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 - birder, 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.">
+17
View File
@@ -0,0 +1,17 @@
---
title: accessibility
---
This website ([leecat.art](/)) aims to be as accessible as possible. To that end, I have tested to the best of my abilities with [NVDA](https://www.nvaccess.org/download/) and [Orca](https://help.gnome.org/orca/index.html), keyboard navigation, and automated review tools.
## Limitations
Because of the nature of a blog with an ever-expanding page list and the fact that I have learned a significant amount in 4 or so years, I cannot guarantee that every article on this site is as accessible as I want it to be. That said, the major pages and navigation have been tested, and I bring my best efforts to every new post.
## Adherence to WCAG 2.2
While I would like to do further structured review and go through the entire list with a finer-tooth comb, my current assessment is that this site meets [WCAG 2.2](https://www.w3.org/WAI/standards-guidelines/wcag/) at least at level AA.
## Feedback
If you meet any barriers in accessing this site, please [contact me](/contact).
+9 -7
View File
@@ -2,17 +2,19 @@
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 is v2 of my personal website, 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.
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.
v1 of this site began in 2022 and was based on [Millennial](https://lenpaul.github.io/Millennial/), 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 header font is [Peritel by Christopher Kirk-Nielsen](https://chriskirknielsen.com/fonts/peritel/). I'm currently trying it on for size, so let me know if you like it - or hate it! The body fonts (and the all-caps headers on the post list pages) are [Atkinson Hyperlegible Next and Atkinson Hyperlegible Mono](https://brailleinstitute.org/freefont) for standard text and monospace respectively, specifically designed for low-vision readers to improve character recognition. Also they look neat :)
The search bar is powered by [Pagefind](https://pagefind.app/). I was guided by [Robb Knight's walkthrough](https://rknight.me/blog/using-pagefind-with-eleventy-for-search/) when setting it up.
Thank you to some lovely friends for their feedback and help with the site! You should hire them. Yes, you.
- [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"}
- [Lenny](http://www.wondra.codes/), especially for their HTML/CSS and accessibility expertise
- [Shir](https://shirgoldberg.com/)
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).
You can [find the accessibility statement here](/accessibility). If you'd like, you can view the [site's palette](/palette) or the [style overview](/style). You can also [explore the sitemap](/sitemap.xml).
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).
+14 -16
View File
@@ -10,12 +10,12 @@ 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-brands fa-signal-messenger"></i> signal</dt>
<dd><a href="https://signal.me/#eu/QcbGX1oHL3vsByOx8808DRW0g53ehYPfu4tAaXx8-Kl7Qdonj-JM6Z3l-QXcqO_d">inherentlee.13</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>
<dd><a href="tel:17742490586">seven seven four, two four nine, zero five eight six</a></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>
@@ -67,31 +67,29 @@ if pricing is an issue for you, reach out and we can work out sliding scale opti
---
## in physical stores!
## in physical stores
Find me at [various art shows and fairs](/art-shows-and-events/).
### Colorado
#### Denver
- [(dis)obedience](https://www.disobediencedenver.com){:target="_blank"}: stickers, pins, cards
- [(dis)obedience](https://www.disobediencedenver.com): stickers, pins, cards
### Oregon
#### Beaverton
- [Forager Vintage](https://foragervintage.com/){:target="_blank"}: stickers, pins, cards
- [Forager Vintage](https://foragervintage.com/): 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
- [Push/Pull](https://www.pushpullseattle.com/): stickers, pins, cards
- [Standard Goods Ballard](https://thestandardgoods.com/pages/ballard): stickers
- [Standard Goods Capitol Hill](https://thestandardgoods.com/pages/capitol-hill): stickers
#### Tacoma
@@ -99,9 +97,9 @@ if pricing is an issue for you, reach out and we can work out sliding scale opti
#### 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
- [Vashon Made (formerly Starving Artist Works) (facebook)](https://www.facebook.com/SawStarvingArtistWorks/): stickers, cards, prints, wallets, handbound books, yarn
- [Standard Goods Vashon](https://thestandardgoods.com/pages/vashon): stickers
- [Vashon Pharmacy](https://vashonpharmacy.com/): cards
---
+5 -7
View File
@@ -7,9 +7,7 @@ yes, you may sign again even if you've been here before - just no spamming pleas
## 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>
Please [use this guestbook form](https://airtable.com/app1YuM4uE4sRTYgh/pag4JzOylrLoLy4AS/form) or just [contact me any way you want](/contact) with your desired message.
## read
@@ -34,7 +32,7 @@ Fern (Rainbow) on <time datetime="2024-09-06">6 September 2024</time>:
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>:
[jay](jaygrant.us) on <time datetime="2024-09-06">6 September 2024</time>:
> EGG
pqqq on <time datetime="2024-09-06">6 September 2024</time>:
@@ -43,16 +41,16 @@ pqqq on <time datetime="2024-09-06">6 September 2024</time>:
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>:
[Lisa](@mycrowgirl@mastodon.social) 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>:
[✨pencilears✨](https://pencilears.eternalaugust.net/comic/) 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>:
[brhfl](https://brhfl.com) 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>:
-201
View File
@@ -1,201 +0,0 @@
---
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>
+328
View File
@@ -0,0 +1,328 @@
---
title: resume
layout: base.njk
---
{% css %}{% include "css/resume.css" %}{% endcss %}
<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, and Javascript</li>
<li>Languages like Go, C, and Python</li>
<li>Relational database theory focused on PostgreSQL</li>
<li>Accessibility knowledge and thoughtful design</li>
</ul>
<hr>
<h2 class="centered upper" id="experience">Experience</h2>
<div class="job">
<div class="two-col job-details">
<h3 id="freelance-web-developer">Freelance Web Developer</h3>
<p class="col2"><time datetime="2026-01">January 2026</time> – Present</p>
</div>
<p>
Creates and maintains websites for clients based off their concepts and
ideas.
</p>
<ul>
<li>
<strong>District Dharma
(<a href="https://districtdharma.org/"
target="_blank">districtdharma.org</a>):</strong>
a clean and minimalist homepage for the District Dharma collective,
built in Eleventy with a Mattrbld content management system to allow
for easy editing by the client.
<blockquote class="testimonial">
Being of a generation that didn't grow up with technology, I was a little
nervous going into this project, but Lee made it easy. He was patient and
completely non-judgmental with my simple questions, quick to respond by
email, and open to my feedback throughout. He built exactly what I
envisioned for our meditation group's website, and his estimate was the
final cost. When he asked what he could improve, I honestly couldn't come
up with anything. He delivered what he promised and was easy to reach the
whole way through. If you want someone skilled who will also make the
process feel comfortable, I can't recommend him highly enough.
</blockquote>
</li>
<li>
<strong>My Liberation Work Has Been Damn Ableist: A Landworker Memoir
(<a href="https://maze-pants.codeberg.page/"
target="_blank">maze-pants.codeberg.page</a>):</strong>
a web-friendly version of Maze's ~70 page zine, built as a single-page
static site.
<blockquote class="testimonial">
...a pleasure to work with. Ze pays close attention to detail, and
truly cares about making his creations accessible, including aspects
that I didn’t even know to ask for. As a bonus ze is extremely quick
and responsive!
</blockquote>
</li>
<li>
<strong>Gryphon's Roost (<a href="https://gryphonsroost.xyz"
target="_blank">gryphonsroost.xyz</a>):</strong>
a major redesign and port of Gryphon's Wix site to an Eleventy and
TinaCMS blog.
<blockquote class="testimonial">I really appreciate your willingness/ability
to meet me where I was at as far as communication and such was. I
feel a lot more comfortable asking clarifying questions than I have
with others.</blockquote>
</li>
<li>
<strong>Mari Hsu (<a href="https://marihsu.com"
target="_blank">marihsu.com</a>):</strong>
a redesign of Mari's existing site and full port from pure HTML/CSS to
Eleventy-based blog.
<blockquote class="testimonial">
Having participated in a few tangible projects that Lee has run online
I have admired hir clean, effective, and attractive websites for a
while. When Lee announced ze was taking on more work, I jumped at the
chance to have someone else rebuild my old handcoded one. My new
website from Lee is fantastic! Super easy to customize and update on
my own, which is what I have wanted for a long time. Ze was easy to
work with, very communicative about details of the process, and well
aligned with what I wanted from my site. I would not hesitate to
recommend Lee to anyone, at any technical comfort level, who wants a
nice website.
</blockquote>
</li>
<li>
<strong>Spoonfairies (<a href="https://spoonfairies.help"
target="_blank">spoonfairies.help</a>):</strong>
an Eleventy-based website for a just-launching project, designed and
built from the ground up.
<blockquote class="testimonial">
...the site dev of my dreams -- ze brought my vision from a
PowerPoint to a webpage with clarity and a focus on accessibility
that made me feel real hope for the future. I am grateful for his
thought partnership and ongoing site support!
</blockquote>
</li>
<li>
<strong>Beall Greenhouses (<a href="https://beall-greenhouses.com"
target="_blank">beall-greenhouses.com</a>):</strong>
a website for the Beall Greenhouses artist studios and markets,
originally pure HTML/CSS/JS before porting to Eleventy for longevity
and ease of maintenance.
<blockquote class="testimonial">
...an absolute delight to work with. His communication is efficient
and timely, and his considerations in design are impeccable. When I
asked him if he could do this project, he came in on a level that I
had not anticipated. His contributions to my event have been
immeasurable. It’s exciting to continue to work with him, as we are
constantly finding new ways to upgrade our interface with the public.
The possibilities that he brings to the table are astounding.
</blockquote>
</li>
</ul>
</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="2018-08">August 2018</time> – <time
datetime="2025-07">July 2025</time></p>
</div>
<h3 id="software-development-engineer-i-ii">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 id="co-owner-and-artist">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 id="undergraduate-programming-mentor">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 id="software-development-engineering-intern">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 id="fedilearns">FediLearns (<a
href="https://fedilearns.fyi" target="_blank">fedilearns.fyi</a>)</h3>
<p class="col2"><time datetime="2026-04">April 2026</time> – Present
</p>
</div>
<p>Designs, develops, and maintains website for learning and skill-sharing
listings for the fediverse (Mastodon). Manages all data and incoming
listing requests.</p>
</div>
<div class="spacer"></div>
<div class="job">
<div class="two-col job-details">
<h3 id="siblinghood-of-the-traveling-greeting-card">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 id="fedizinefest">FediZineFest (<a href="https://fedizinefest.fyi"
target="_blank">fedizinefest.fyi</a>)</h3>
<p class="col2"><time datetime="2023-12">December 2023</time> – Present</p>
</div>
<p>Creates and runs a global event for zine artists on the fediverse, now in its
third year. Coordinates website, physical material shipping and
logistics, payment, and marketing for a 40–50 person project. Leads a small team
and delegates appropriate responsibilities.</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, develops, maintains, and creates all content.</p>
</div>
<div class="spacer"></div>
<div class="job">
<div class="two-col job-details">
<h3 id="rescue-trans-rescue">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" id="education">Education</h2>
<p class="centered">
<b>Bachelor of Science — Computer Science</b>
<br />
Rensselaer Polytechnic Institute, Troy, NY
</p>
</div>
+2
View File
@@ -110,6 +110,8 @@ Code blocks can have syntax highlighting:
<h1>Hello, world</h1>
```
### You can even write `headers in monospace`
## Tables
Tables in Markdown are kind of annoying to format. You use the pipe (`|`) character as well as dashes.
+1 -1
View File
@@ -8,4 +8,4 @@ tags:
- gender
---
an incomplete list of books by/for/about queer folks. <a href="https://docs.google.com/document/d/1wqLtUeow59XHp7QfRhGcyufywEvSCh4ed8kYST4F0Yk/edit?usp=sharing" target="_blank">check it out and add your favorites.</a>
an incomplete list of books by/for/about queer folks. [check it out and add your favorites](https://docs.google.com/document/d/1wqLtUeow59XHp7QfRhGcyufywEvSCh4ed8kYST4F0Yk/edit?usp=sharing).
@@ -8,7 +8,7 @@ tags:
- book
---
A green journal with a blue leather spine. The coloring pages are from the book [Color Acadia](https://www.ellsworthamerican.com/living/arts-a-living/color-acadia/){target="_blank" rel="external"} with art by Katie Dube and Keri Kimura.
A green journal with a blue leather spine. The coloring pages are from the book [Color Acadia](https://www.ellsworthamerican.com/living/arts-a-living/color-acadia/) with art by Katie Dube and Keri Kimura.
## details
+1 -1
View File
@@ -8,7 +8,7 @@ tags:
- book
---
A leather spine journal with a striped front cover and navy back cover. It includes both blank pages and fold-out coloring pages from [Fantastic Cities](https://bookshop.org/p/books/fantastic-cities-a-coloring-book-of-amazing-places-real-and-imagined-adult-coloring-books-city-coloring-books-coloring-books-for-adu-steve-mcdonald/7572265?ean=9781452149578){target="_blank" rel="external"} by Steve McDonald.
A leather spine journal with a striped front cover and navy back cover. It includes both blank pages and fold-out coloring pages from [Fantastic Cities](https://bookshop.org/p/books/fantastic-cities-a-coloring-book-of-amazing-places-real-and-imagined-adult-coloring-books-city-coloring-books-coloring-books-for-adu-steve-mcdonald/7572265?ean=9781452149578) by Steve McDonald.
## details
+1 -1
View File
@@ -8,7 +8,7 @@ tags:
- book
---
A small highlighter-orange journal with blank fold-out pages and floral coloring pages, including flocked pages, from [BLOOM](https://www.bluestarpress.com/product/bloom-a-coloring-book/){target="_blank" rel="external"} by Alli Koch.
A small highlighter-orange journal with blank fold-out pages and floral coloring pages, including flocked pages, from [BLOOM](https://www.bluestarpress.com/product/bloom-a-coloring-book/) by Alli Koch.
## details
+1 -1
View File
@@ -8,4 +8,4 @@ tags:
- knit
---
My second pair of socks, knit for my partner. They use [Schoppel-Wolle](https://www.schoppel-wolle.de/){target="_blank" rel="external"} Das Paar yarn in the colorway Fruhjahrsputz / Spring Cleaning. This yarn is designed to produce identical striping for each sock, and it very nearly did, with only a tiny discrepancy notable as I got to the toes.
My second pair of socks, knit for my partner. They use [Schoppel-Wolle](https://www.schoppel-wolle.de/) Das Paar yarn in the colorway Fruhjahrsputz / Spring Cleaning. This yarn is designed to produce identical striping for each sock, and it very nearly did, with only a tiny discrepancy notable as I got to the toes.
+1 -1
View File
@@ -8,4 +8,4 @@ tags:
- knit
---
My first pair of socks, knit with [Seattle Sky Dyeworks](https://seattleskydyeworks.com/){target="_blank" rel="external"} Temporum yarn in colorway Salmon Run.
My first pair of socks, knit with [Seattle Sky Dyeworks](https://seattleskydyeworks.com/) Temporum yarn in colorway Salmon Run.
+20 -16
View File
@@ -10,37 +10,41 @@ tags:
## Articles
- [Critic of the Dawn](http://raggededgemagazine.com/0501/0501cov.htm){target="_blank" rel="external"} by Cal Montgomery
- [pronouns aren't gender; please get better at looking at birds](https://kconrod.medium.com/pronouns-arent-gender-please-get-better-at-looking-at-birds-8e6310ef455a){target="_blank" rel="external"} by Kirby Conrod
- [Critic of the Dawn](http://raggededgemagazine.com/0501/0501cov.htm) by Cal Montgomery
- [pronouns aren't gender; please get better at looking at birds](https://kconrod.medium.com/pronouns-arent-gender-please-get-better-at-looking-at-birds-8e6310ef455a) by Kirby Conrod
## Books
- [Camp Damascus](https://bookshop.org/p/books/camp-damascus-chuck-tingle/18738983){target="_blank" rel="external"} by Chuck Tingle
- [How We Get Free](https://bookshop.org/p/books/how-we-get-free-black-feminism-and-the-combahee-river-collective-keeanga-yamahtta-taylor/8203276?ean=9781608468553){target="_blank" rel="external"} ed. by Keeanga-Yamahtta Taylor
- [Laziness Does Not Exist](https://bookshop.org/p/books/laziness-does-not-exist-devon-price/14871468){target="_blank" rel="external"} by Devon Price, PhD
- [The Soul of a New Machine](https://bookshop.org/p/books/the-soul-of-a-new-machine-tracy-kidder/113845){target="_blank" rel="external"} by Tracy Kidder
- [Stone Butch Blues](https://www.lesliefeinberg.net/){target="_blank" rel="external"} by Leslie Feinberg
- [Whipping Girl](https://bookshop.org/p/books/whipping-girl-lib-e-a-transsexual-woman-on-sexism-and-the-scapegoating-of-femininity-julia-serano/12413169){target="_blank" rel="external"} by Julia Serano
- [Camp Damascus](https://bookshop.org/p/books/camp-damascus-chuck-tingle/18738983) by Chuck Tingle
- [How We Get Free](https://bookshop.org/p/books/how-we-get-free-black-feminism-and-the-combahee-river-collective-keeanga-yamahtta-taylor/8203276?ean=9781608468553) ed. by Keeanga-Yamahtta Taylor
- [Laziness Does Not Exist](https://bookshop.org/p/books/laziness-does-not-exist-devon-price/14871468) by Devon Price, PhD
- [The Soul of a New Machine](https://bookshop.org/p/books/the-soul-of-a-new-machine-tracy-kidder/113845) by Tracy Kidder
- [Stone Butch Blues](https://www.lesliefeinberg.net/) by Leslie Feinberg
- [Whipping Girl](https://bookshop.org/p/books/whipping-girl-lib-e-a-transsexual-woman-on-sexism-and-the-scapegoating-of-femininity-julia-serano/12413169) by Julia Serano
## Comedy
- [Douglas](https://www.netflix.com/title/81054700){target="_blank" rel="external"} by Hannah Gadsby
- [Douglas](https://www.netflix.com/title/81054700) by Hannah Gadsby
## Comics
- [Ten Thousand](https://xkcd.com/1053/){target="_blank" rel="external"} by Randall Munroe
- [Ten Thousand](https://xkcd.com/1053/) by Randall Munroe
## Movies
- [To Wong Foo, Thanks for Everything! Julie Newmar](https://www.imdb.com/title/tt0114682/)
## Short fiction
- [Why Don't We Just Kill the Kid in the Omelas Hole](https://clarkesworldmagazine.com/kim_02_24/){target="_blank" rel="external"} by Isabel J. Kim
- [Why Don't We Just Kill the Kid in the Omelas Hole](https://clarkesworldmagazine.com/kim_02_24/) by Isabel J. Kim
## Social media threads
- [It's 2026 and you wonder what your friends are up to.](https://retro.social/@ifixcoinops/113838462085835742){target="_blank" rel="external"} by [@ifixcoinops@retro.social](https://retro.social/@ifixcoinops){:target="_blank"}
- [It's 2026 and you wonder what your friends are up to.](https://retro.social/@ifixcoinops/113838462085835742) by [@ifixcoinops@retro.social](https://retro.social/@ifixcoinops)
## Videos
- (Playlist) [The Alt-Right Playbook](https://www.youtube.com/playlist?list=PLJA_jUddXvY7v0VkYRbANnTnzkA_HMFtQ){target="_blank" rel="external"} by Innuendo Studios
- [Did feminism FAIL men?](https://www.youtube.com/watch?v=UOhs9jxe4lM){target="_blank" rel="external"} by Alexander Avila
- [The Kronk Effect](https://www.youtube.com/watch?v=5Sz40XPPtKQ){target="_blank" rel="external"} by CJ the X
- (Playlist) [Pretty Good](https://www.youtube.com/playlist?list=PLUXSZMIiUfFSCYW1o-4whWtepyVlsfuCC){target="_blank" rel="external"} by Jon Bois and Secret Base
- (Playlist) [The Alt-Right Playbook](https://www.youtube.com/playlist?list=PLJA_jUddXvY7v0VkYRbANnTnzkA_HMFtQ) by Innuendo Studios
- [Did feminism FAIL men?](https://www.youtube.com/watch?v=UOhs9jxe4lM) by Alexander Avila
- [The Kronk Effect](https://www.youtube.com/watch?v=5Sz40XPPtKQ) by CJ the X
- (Playlist) [Pretty Good](https://www.youtube.com/playlist?list=PLUXSZMIiUfFSCYW1o-4whWtepyVlsfuCC) by Jon Bois and Secret Base
+2 -1
View File
@@ -1,5 +1,6 @@
---
title: butch hands pattern
layout: post-with-toc.njk
image:
src: 2023/butch-hands.jpg
alt: "Hands wearing a pair of pink and grey gloves with convertable mitten tops."
@@ -16,7 +17,7 @@ This pattern is a **Work in Progress** and will be updated with more information
- Created: 12 March 2021
- Last updated: 13 February 2023
This pattern was built on the [Podster Gloves pattern](https://www.ravelry.com/patterns/library/podster-gloves){target="_blank" rel="external"} by Glenna C. on Ravelry. I highly recommend reading and following that pattern to fill in gaps with this one.
This pattern was built on the [Podster Gloves pattern](https://www.ravelry.com/patterns/library/podster-gloves) by Glenna C. on Ravelry. I highly recommend reading and following that pattern to fill in gaps with this one.
## Materials and tools
+1 -1
View File
@@ -10,7 +10,7 @@ tags:
- shirt
---
Hand carved stamp of a great blue heron. Based on a photo from [birdpixel](birdpixel.com){target="_blank" rel="external"}.
Hand carved stamp of a great blue heron. Based on a photo from [birdpixel](birdpixel.com).
## details
+12 -10
View File
@@ -3,28 +3,30 @@ title: block printing transfer method
image:
src: 2023/transfer-wip.jpg
alt: "A pink block of carving material with a printed design of a bird attached to it. The paper has been partially rubbed away (process described in this post) to reveal the inked design on the carving material."
tags:
- print
---
## materials
### for transfer
- [speedy-carve](https://www.dickblick.com/products/speedball-speedy-carve-blocks/){target="_blank" rel="external"}
- I have since also used [moo carve](https://www.dickblick.com/products/moo-carve-professional-carving-blocks/){target="_blank" rel="external"} and been successful
- [speedy-carve](https://www.dickblick.com/products/speedball-speedy-carve-blocks/)
- I have since also used [moo carve](https://www.dickblick.com/products/moo-carve-professional-carving-blocks/) and been successful
- laserjet printed or xerox'd image, preferably something with high contrast
- acrylic gel medium - I use [Golden Soft Gel Matte](https://www.dickblick.com/items/golden-soft-acrylic-gel-medium-matte-16-oz-jar/){target="_blank" rel="external"}
- acrylic gel medium - I use [Golden Soft Gel Matte](https://www.dickblick.com/items/golden-soft-acrylic-gel-medium-matte-16-oz-jar/)
- paintbrush
- [brayer](https://www.dickblick.com/products/testrite-foam-brayer/){target="_blank" rel="external"}
- [brayer](https://www.dickblick.com/products/testrite-foam-brayer/)
### for carving
- carving tool(s) such as [speedball carving tool](https://www.dickblick.com/products/speedball-linoleum-cutters/){target="_blank" rel="external"} or [flexcut carving tools](https://www.dickblick.com/products/flexcut-lino-relief-printmaking-set/){:target="_blank"}
- carving tool(s) such as [speedball carving tool](https://www.dickblick.com/products/speedball-linoleum-cutters/) or [flexcut carving tools](https://www.dickblick.com/products/flexcut-lino-relief-printmaking-set/)
- I use a narrow V tool from flexcut and large/small U tools from speedball at current
### for printing
- my favorite stamping ink at current is [VersaFine](https://www.tsukineko.co.jp/english/detail/versafine/index.html){target="_blank" rel="external"}
- (edit 18 Sep 2023) I have since used [Speedball fabric block printink inks](https://www.dickblick.com/products/speedball-fabric-paper-block-printing-ink/){target="_blank" rel="external"}. Preferable for fabric.
- my favorite stamping ink at current is [VersaFine](https://www.tsukineko.co.jp/english/detail/versafine/index.html)
- (edit 18 Sep 2023) I have since used [Speedball fabric block printink inks](https://www.dickblick.com/products/speedball-fabric-paper-block-printing-ink/). Preferable for fabric.
## process
@@ -37,6 +39,6 @@ image:
## references
- [3 methods for transfer including PVA glue transfer](https://www.jacksonsart.com/blog/2021/11/19/the-best-way-to-transfer-images-to-lino/){target="_blank" rel="external"}
- [gel medium transfer onto label paper](https://www.youtube.com/watch?v=EmKVw72mm5Q){target="_blank" rel="external"}
- [4 methods for transfer including gel medium transfer](https://www.youtube.com/watch?v=XD8AyNOisFw){target="_blank" rel="external"}
- [3 methods for transfer including PVA glue transfer](https://www.jacksonsart.com/blog/2021/11/19/the-best-way-to-transfer-images-to-lino/)
- [gel medium transfer onto label paper](https://www.youtube.com/watch?v=EmKVw72mm5Q)
- [4 methods for transfer including gel medium transfer](https://www.youtube.com/watch?v=XD8AyNOisFw)
@@ -1,5 +1,6 @@
---
title: backend accessibility
layout: post-with-toc.njk
image:
src: 2023/camelCase-print.jpg
alt: "A carved stamp next to its print. The print reads '#camelCase' in a slightly formal-looking italic font."
@@ -8,7 +9,7 @@ tags:
- software
---
> These notes are from a talk I gave at work. If you think something is missing or incorrect, please let me know!
These notes are from a talk I gave at work. If you think something is missing or incorrect, please let me know!
Backend developers still have users: other developers. We're all human, with human limitations and differences. Design for those limitations and you'll find you improve the end result for everyone.
@@ -64,23 +65,23 @@ These are bits of feedback or further thoughts that have yet to be integrated in
## References
- [Accessibility guidelines and requirements — Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/accessibility/accessibility-guidelines-requirements){target="_blank" rel="external"}
- [Write accessible documentation — Google docs style guide](https://developers.google.com/style/accessibility){target="_blank" rel="external"}
- [Is it accessible? — Adrian Roselli](https://adrianroselli.com/2024/08/things-to-do-before-asking-is-this-accessible.html){target="_blank" rel="external"}
- [Collected accessibility resources — Marco Salsiccia](https://marconius.com/a11yLinks/){target="_blank" rel="external"}
- [A11y coffee](https://a11y.coffee/start-testing/){target="_blank" rel="external"} [note: spell out 'accessibility' rather than shortening to 'a11y'!]
- [Accessibility guidelines and requirements — Microsoft style guide](https://learn.microsoft.com/en-us/style-guide/accessibility/accessibility-guidelines-requirements)
- [Write accessible documentation — Google docs style guide](https://developers.google.com/style/accessibility)
- [Is it accessible? — Adrian Roselli](https://adrianroselli.com/2024/08/things-to-do-before-asking-is-this-accessible.html)
- [Collected accessibility resources — Marco Salsiccia](https://marconius.com/a11yLinks/)
- [A11y coffee](https://a11y.coffee/start-testing/) [note: spell out 'accessibility' rather than shortening to 'a11y'!]
### Alt text/image descriptions
- [How to write an image description](https://uxdesign.cc/how-to-write-an-image-description-2f30d3bf5546){target="_blank" rel="external"}
- [How to write alt text and image descriptions for the visually impaired — Perkins School for the Blind](https://www.perkins.org/resource/how-write-alt-text-and-image-descriptions-visually-impaired/){target="_blank" rel="external"}
- [An attempted guide to writing effective alt and descriptive text for art](https://mannequinrentals.help/2024/03/21/an-attempted-guide-to-writing-effective-alt-and-descriptive-text-for-art/){target="_blank" rel="external"}
- [Alt text as poetry](https://alt-text-as-poetry.net/){target="_blank" rel="external"}
- [Writing alt text for a scientific figure - Kristin Briney](http://dataabinitio.com/?p=1161){target="_blank" rel="external"}
- [How to write an image description](https://uxdesign.cc/how-to-write-an-image-description-2f30d3bf5546)
- [How to write alt text and image descriptions for the visually impaired — Perkins School for the Blind](https://www.perkins.org/resource/how-write-alt-text-and-image-descriptions-visually-impaired/)
- [An attempted guide to writing effective alt and descriptive text for art](https://mannequinrentals.help/2024/03/21/an-attempted-guide-to-writing-effective-alt-and-descriptive-text-for-art/)
- [Alt text as poetry](https://alt-text-as-poetry.net/)
- [Writing alt text for a scientific figure - Kristin Briney](http://dataabinitio.com/?p=1161)
- [My approach to alt text - Adrian Roselli](https://adrianroselli.com/2024/05/my-approach-to-alt-text.html)
### Other specific topics
- [Tabs vs. spaces - Adam Tuttle](https://adamtuttle.codes/blog/2021/tabs-vs-spaces-its-an-accessibility-issue/){target="_blank" rel="external"}
- [Accessible numbers](https://accessiblenumbers.com){target="_blank" rel="external"}
- [Chartability](https://chartability.fizz.studio){target="_blank" rel="external"} (data visualization)
- [Tabs vs. spaces - Adam Tuttle](https://adamtuttle.codes/blog/2021/tabs-vs-spaces-its-an-accessibility-issue/)
- [Accessible numbers](https://accessiblenumbers.com)
- [Chartability](https://chartability.fizz.studio) (data visualization)
+1 -1
View File
@@ -10,7 +10,7 @@ tags:
- shirt
---
Hand carved set of stamps depicting a stellar's jay about to take off. Based on a photo from [birdpixel](birdpixel.com){target="_blank" rel="external"}.
Hand carved set of stamps depicting a stellar's jay about to take off.
## details
+1 -1
View File
@@ -9,7 +9,7 @@ tags:
- card
- shirt
---
A large, *large* pigeon. Based on a fantastic photograph by [Chris Price](https://studiochris.us/){target="_blank" rel="external"}.
A large, *large* pigeon. Based on a fantastic photograph by [Chris Price](https://studiochris.us/).
## details
+1 -1
View File
@@ -10,7 +10,7 @@ tags:
- shirt
---
Based on a fantastic picture by [handmade ghost](https://mstdn.games/@handmade_ghost){target="_blank" rel="external"}
Based on a fantastic picture by [handmade ghost](https://mstdn.games/@handmade_ghost)
## details
@@ -8,7 +8,7 @@ tags:
- book
---
Includes coloring pages from [Animorphia by Kerby Rosanes](https://kerbyrosanes.com/animorphia){target="_blank" rel="external"}.
Includes coloring pages from [Animorphia by Kerby Rosanes](https://kerbyrosanes.com/animorphia).
## details
@@ -3,6 +3,8 @@ title: printing press notes
image:
src: 2023/printing-press.jpg
alt: "An open Speedball Model B printing press, which uses a lever handle to put even pressure on a 6 by 8 inch top plate."
tags:
- reference
---
## specs
+21 -22
View File
@@ -92,8 +92,8 @@ In order to more easily discuss these topics, I will note here my working defini
There's a dearth of data on trans individuals. That said, we do have some relevant sources that have given us broad insight into trans communities.
- [U.S. Transgender Survey](https://www.ustranssurvey.org/reports){target="_blank" rel="external"}, the largest survey ever devoted to the lives and experiences of transgender people, with 27,715 respondents across the United States.
- [Gender Census](https://www.gendercensus.com/){target="_blank" rel="external"}, an annual survey that collects information about the language used by people whose genders are not adequately described, expressed or encompassed by the restrictive gender binary.
- [U.S. Transgender Survey](https://www.ustranssurvey.org/reports), the largest survey ever devoted to the lives and experiences of transgender people, with 27,715 respondents across the United States.
- [Gender Census](https://www.gendercensus.com/), an annual survey that collects information about the language used by people whose genders are not adequately described, expressed or encompassed by the restrictive gender binary.
Both of these sources use ‘nonbinary’ as their usual spelling; I am mirroring that here.
@@ -107,7 +107,7 @@ It's always worthwhile to stop and look at how relevant or necessary gender info
>
> "If you’re collecting gender identity data to personalize user-facing copy, try asking for preferred pronouns instead. If you’re asking because you want to make in-app content recommendations, try asking about the user’s content preferences. If you’re asking to generate a user avatar, let the user generate their own. Gender identity is a poor proxy variable — stick to asking for the information you actually want.
[(Hunter, 2020)](https://builtin.com/software-engineering-perspectives/trans-inclusivity-tips-developers){target="_blank" rel="external"}
[(Hunter, 2020)](https://builtin.com/software-engineering-perspectives/trans-inclusivity-tips-developers)
Drupal's gender field includes the following guidance in its description:
@@ -118,7 +118,7 @@ Drupal's gender field includes the following guidance in its description:
> 5. Do you want to publicly display a person's gender on a profile? This is often a choice made by social media and dating/relationship sites. If you do this, consider making the field optional altogether. If you are providing user avatars, remember that human bodies come in all sorts, and allow individuals to choose an avatar separately from collecting this data.
> 6. Do you need to know assigned gender for legal, medical or regulatory reasons? Current gender does not necessarily correspond to assigned sex at birth or legal gender marker, so be sure you are clear in what you are requesting of a person. It's particularly critical to be transparent about your privacy policy and the how this data will be used.
[(McCabe and Beach, 2019)](https://www.drupal.org/project/gender){target="_blank" rel="external"}
[(McCabe and Beach, 2019)](https://www.drupal.org/project/gender)
### Safety and prevention of abuse
@@ -128,7 +128,7 @@ Drupal's gender field includes the following guidance in its description:
>
> Instead of putting the burden on a user to fully understand the risks of sharing their highly personal information, let’s put the burden on ourselves to treat that information right. If we have no strong reason to collect it, or can’t guarantee its safety, we shouldn’t collect it.
[(Spicknall, 2019)](https://medium.com/@SorenSpicknall/protecting-queer-communities-through-data-4707ae0cb562){target="_blank" rel="external"}
[(Spicknall, 2019)](https://medium.com/@SorenSpicknall/protecting-queer-communities-through-data-4707ae0cb562)
If you do collect gender data, inform the user what it is used for and who it will be shared with.
@@ -138,7 +138,7 @@ If you do collect gender data, inform the user what it is used for and who it wi
The availability of nonbinary gender options in legal systems varies by location. The ability to change one's gender marker (from one binary category to another or from binary to nonbinary) varies even more widely, with requirements ranging from simple voluntary declaration, to verification by medical professional(s) of varying treatments which vary in how accessible they are and whether they are actually desired by individuals for whom this is relevant, to only changing in response to proven "error," etc.
[(Transgender Law Center, 2017)](http://transgenderlawcenter.org/wp-content/uploads/2016/12/Birth-Cert-overview-state-by-state.pdf){target="_blank" rel="external"} [(Movement Advancement Project)](https://www.lgbtmap.org/equality-maps/identity_document_laws){:target="_blank"} [(Knight and Ghosal, 2016)](https://www.hrw.org/world-report/2016/country-chapters/africa-americas-asia-europe/central-asia-middle-east/north-0){:target="_blank"}
[(Transgender Law Center, 2017)](http://transgenderlawcenter.org/wp-content/uploads/2016/12/Birth-Cert-overview-state-by-state.pdf) [(Movement Advancement Project)](https://www.lgbtmap.org/equality-maps/identity_document_laws) [(Knight and Ghosal, 2016)](https://www.hrw.org/world-report/2016/country-chapters/africa-americas-asia-europe/central-asia-middle-east/north-0)
If you are not specifically trying to refer to an individual’s legal identification, don’t tie gender to it.
@@ -154,7 +154,7 @@ This is variously defined to refer to sex assigned at birth, legal gender/sex ma
and more. This identifier may or may not be treated as binary and may or may not take into account an individual's medical history.
[(Montañez, 2017)](https://blogs.scientificamerican.com/sa-visual/visualizing-sex-as-a-spectrum/){target="_blank" rel="external"}
[(Montañez, 2017)](https://blogs.scientificamerican.com/sa-visual/visualizing-sex-as-a-spectrum/)
Outside of healthcare, this is largely unnecessary. For healthcare, see [Two- or multi- step approach](#two--or-multi--step-approach) and [Organ inventory](#organ-inventory).
@@ -164,7 +164,7 @@ As a way to accurately represent gender diverse people, "other" is, quite litera
> "Researchers have also developed methods to respond to challenges involved in data collection about sexual and gender identities which are culturally specific and unique. For example, in 2011, the government of Nepal attempted the world’s first census in which respondents had the option of choosing 'Male,' 'Female,' or 'Third Gender.' The effort was not successful for a number of reasons, among which was that large proportions of the gender minority population did not identify with the term 'third gender.' Subsequent research determined that the use of culturally specific terms such as 'Methi' and 'Kothi' would have increased the effectiveness of the census effort."
[(Park, 2016)](https://williamsinstitute.law.ucla.edu/publications/data-collection-sogi/){target="_blank" rel="external"}
[(Park, 2016)](https://williamsinstitute.law.ucla.edu/publications/data-collection-sogi/)
### Expansive lists
@@ -183,11 +183,11 @@ For smaller projects, however, this is still an option. Or you can offer this to
### Assumptions that a single term will fully encompass gender, especially in a more exhaustive list of options
Especially when providing expansive lists or allowing write in fields, ensure that terms that are not mutually exclusive must be chosen as though they are. This is the reasoning behind guidance for a two-step approach, described in more detail in [Two- or multi- step approach](#two--or-multi--step-approach), which "measures assigned sex at birth and self-reported gender identity at the time of the survey" [(Park, 2016)](https://williamsinstitute.law.ucla.edu/publications/data-collection-sogi/){target="_blank" rel="external"}
Especially when providing expansive lists or allowing write in fields, ensure that terms that are not mutually exclusive must be chosen as though they are. This is the reasoning behind guidance for a two-step approach, described in more detail in [Two- or multi- step approach](#two--or-multi--step-approach), which "measures assigned sex at birth and self-reported gender identity at the time of the survey" [(Park, 2016)](https://williamsinstitute.law.ucla.edu/publications/data-collection-sogi/)
> "...some terms aren’t mutually exclusive, and framing them as such is offensive, Mons said: 'For example, if we list Man, Woman, Non-Binary, Trans Man and Trans Woman, **does that separation imply that someone who is trans and identifies as a man is not a man?**'"
[(Gossett, 2020)](https://builtin.com/data-science/dscout-gender-identity-data-practice){target="_blank" rel="external"} emphasis mine
[(Gossett, 2020)](https://builtin.com/data-science/dscout-gender-identity-data-practice) emphasis mine
### Automatic detection of gender
@@ -195,7 +195,7 @@ In addition to reinforcing binarism, this approaches tends to reinforce sexism a
> "Moreover, these works tend to codify (literally, to write into code) essentialist, stereotypical characterizations of male and female communication patterns and present them as universal, context-free, scientific truths."
[(kanarinka, 2016)](https://civic.mit.edu/index.html%3Fp=1165.html){target="_blank" rel="external"}
[(kanarinka, 2016)](https://civic.mit.edu/index.html%3Fp=1165.html)
For transgender individuals, automatic categorization as a gender they are not is often a frequent and painful occurrence. We should take care not to introduce unnecessary causes of harm into our systems, especially when they are less accurate and helpful than user self-identification.
@@ -226,7 +226,7 @@ This may also be expanded to a multi-step approach, with questions covering some
- Sex assigned at birth
- Legal gender/sex designation
- Transgender status
- This may additionally benefit from self-identification as "gender diverse, gender non-conforming, gender variant, or gender expansive" [(Stevens)](https://nikkistevens.com/open-demographics/questions/gender.html){target="_blank" rel="external"} either in the same question or as an additional question
- This may additionally benefit from self-identification as "gender diverse, gender non-conforming, gender variant, or gender expansive" [(Stevens)](https://nikkistevens.com/open-demographics/questions/gender.html) either in the same question or as an additional question
- Intersex status
…but only if the data is necessary.
@@ -239,11 +239,11 @@ This may also be expanded to a multi-step approach, with questions covering some
>
> These procedures, however, also should also be un-coupled from any gender-coded template so that an individual coded as male who has had a hysterectomy, for example, could have that history documented. In addition, sex-specific organ procedures and diagnoses relating to these organs should be un-coupled, so that (as an example) a prostatic ultrasound may be ordered on a patient registered as female, or a cervical pap smear ordered on a patient registered as male. Such practices would allow enhanced decision support for transgender-specific care, such as medication interactions, organ- and sex-specific preventive health alerts, or accommodations for sex-specific laboratory normal value ranges.
[(Deutsch, et. al, 2013)](https://www.healthit.gov/isa/sites/isa/files/2017-11/JAMIA%20-%20Transgender%20Health%20and%20EMRs.pdf){target="_blank" rel="external"}
[(Deutsch, et. al, 2013)](https://www.healthit.gov/isa/sites/isa/files/2017-11/JAMIA%20-%20Transgender%20Health%20and%20EMRs.pdf)
Refer to the reference linked above for detailed examples of organ or surgical history inventories.
Additional reference (added Sep 2024): [(Bourns, 2023)](https://www.rainbowhealthontario.ca/wp-content/uploads/2021/09/Guidelines-FINAL-4TH-EDITION-With-2023-Updates.pdf){target="_blank" rel="external"}
Additional reference (added Sep 2024): [(Bourns, 2023)](https://www.rainbowhealthontario.ca/wp-content/uploads/2021/09/Guidelines-FINAL-4TH-EDITION-With-2023-Updates.pdf)
### Differentiate with ‘cis’ and ‘trans’
@@ -259,32 +259,31 @@ Healthcare systems in particular may benefit from [Organ inventory](#organ-inven
### WPATH guidelines on EMR
- WPATH: World Professional Association for Transgender Health [(WPATH, 2023)](https://wpath.org/about/mission-and-vision){target="_blank" rel="external"}
- WPATH: World Professional Association for Transgender Health [(WPATH, 2023)](https://wpath.org/about/mission-and-vision)
- EMR: Electronic Medical Records
> Preferred name, gender identity, and pronoun preference, as identified by patients, should be included as demographic variables (such as with ethnicity). These would be captured in readily amendable, optional fields that are separate from the patient’s state-listed name and sex or gender designation, which may continue to be used for billing purposes in circumstances when the patient has not yet obtained legal change of name and/or sex or gender designation. Note that some patients may identify as ‘genderqueer’ and prefer the use of neither pronoun. While lists of current common gender identities, sex options, and pronoun options are provided [in original document, see source], ideally field parameters would be easily amended to reflect changing paradigms and social trends within transgender communities.
[(Deutsch, et. al, 2013)](https://www.healthit.gov/isa/sites/isa/files/2017-11/JAMIA%20-%20Transgender%20Health%20and%20EMRs.pdf){target="_blank" rel="external"}
[(Deutsch, et. al, 2013)](https://www.healthit.gov/isa/sites/isa/files/2017-11/JAMIA%20-%20Transgender%20Health%20and%20EMRs.pdf)
### Facebook
> "In 2014, Facebook expanded their gender options from 2 to 58 for English speakers in the US and UK. The gender options they added were created in consultation with the LGBTQIA community and range from 'gender non-conforming' to 'two-spirit' to 'trans female'. The corporation later added the ability to identify as more than one gender and to input a custom gender. ... While these changes may appear to be progressive, Facebook’s databases still resolve custom and non-binary genders to Male and Female on the backend based on the binary gender that users select at sign-up where the custom option is not available. Here is how the Facebook Marketing API views gender: 1 = Male, 2 = Female. So while a user and her friends may see her presented as the gender she elects, she is a 1 = Male or 2 = Female to any advertisers looking to purchase her attention."
[(kanarinka, 2016)](https://civic.mit.edu/index.html%3Fp=1165.html){target="_blank" rel="external"}
[(kanarinka, 2016)](https://civic.mit.edu/index.html%3Fp=1165.html)
### Drupal
Uses a list of genders developed by the Open Demographics project. [(McCabe and Beach, 2019)](https://www.drupal.org/project/gender){target="_blank" rel="external"} [(Stevens)](https://nikkistevens.com/open-demographics/questions/gender.html){:target="_blank"}
Uses a list of genders developed by the Open Demographics project. [(McCabe and Beach, 2019)](https://www.drupal.org/project/gender) [(Stevens)](https://nikkistevens.com/open-demographics/questions/gender.html)
### Salesforce Health Cloud
Includes Male, Female, Other, and Decline to Specify as options for a gender field, and the field can be null. [(Salesforce)](https://developer.salesforce.com/docs/atlas.en-us.health_cloud_object_reference.meta/health_cloud_object_reference/health_contact_custom_fields.htm#!){target="_blank" rel="external"}
Includes Male, Female, Other, and Decline to Specify as options for a gender field, and the field can be null. [(Salesforce)](https://developer.salesforce.com/docs/atlas.en-us.health_cloud_object_reference.meta/health_cloud_object_reference/health_contact_custom_fields.htm#!)
### Adobe XDM
Includes Male, Female, Not Specified, and Non-specific. Defaults to not specifed. [(Adobe)](https://experienceleague.adobe.com/docs/experience-platform/xdm/field-groups/profile/demographic-details.html){target="_blank" rel="external"} [(Adobe)](https://github.com/adobe/xdm/blob/master/components/datatypes/person/person.schema.json#L50){:target="_blank"}
Includes Male, Female, Not Specified, and Non-specific. Defaults to not specifed. [(Adobe)](https://experienceleague.adobe.com/docs/experience-platform/xdm/field-groups/profile/demographic-details.html) [(Adobe)](https://github.com/adobe/xdm/blob/master/components/datatypes/person/person.schema.json#L50)
### Epic Healthcare EMR
Uses three different fields: sex assigned at birth, legal sex and gender identity. [(Landman, 2017)](https://www.wired.com/story/the-battle-to-get-gender-identity-into-your-health-records/){target="_blank" rel="external"}
Uses three different fields: sex assigned at birth, legal sex and gender identity. [(Landman, 2017)](https://www.wired.com/story/the-battle-to-get-gender-identity-into-your-health-records/)
+1 -1
View File
@@ -8,7 +8,7 @@ tags:
- shirt
---
hand-printed designs on [bella & canvas](https://shop.bellacanvas.com/){target="_blank" rel="external"} shirts. To order, ~~fill out this form~~ (Sep 2024: no longer taking orders via this method). Or just message me.
hand-printed designs on [bella & canvas](https://shop.bellacanvas.com/) shirts. To order, ~~fill out this form~~ (Sep 2024: no longer taking orders via this method). Or just message me.
See the [shirt tag](tag/shirt) to view available designs.
Loaded 100 of 174 files, more files were not shown because too many files have changed in this diff. Show more