<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Astra Bun | Posts</title>
  <subtitle>Posts by Astra</subtitle>
  <link href="https://astrabun.com/feed.xml" rel="self" />
  <link href="https://astrabun.com/" />
  <updated>2026-05-04T04:00:00Z</updated>
  <id>https://astrabun.com/</id>
  <author>
    <name>Astra Bun</name>
  </author>
  <entry>
    <title>sonasky</title>
    <link href="https://astrabun.com/projects/sonasky/" />
    <updated>2024-08-17T00:00:00Z</updated>
    <id>https://astrabun.com/projects/sonasky/</id>
    <content type="html">&lt;h3&gt;project: sonasky&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: This project has been updated since the original publish date of Sat Aug 17 2024 00:00:00 GMT+0000 (Coordinated Universal Time). See &lt;a href=&quot;https://astrabun.com/projects/sonasky/#updates&quot;&gt;Updates&lt;/a&gt; for details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;about&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://bsky.app/profile/sonasky.bsky.social&quot; target=&quot;_blank&quot;&gt;SonaSky&lt;/a&gt; is a Bluesky Labeler providing fursona species account labels for furry users on the platform.&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/ip9LIBeEPN-2378.webp 2378w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/ip9LIBeEPN-2378.jpeg&quot; alt=&quot;A screenshot of one of Astra&#39;s Bluesky posts showing several labels applied to their account. The first two are from another labeler for pronouns, but the third says &amp;quot;Rabbit&amp;quot;, denoting that is Astra&#39;s fursona species.&quot; width=&quot;2378&quot; height=&quot;697&quot;&gt;&lt;/picture&gt;&lt;br&gt;
&lt;em&gt;The first two labels are pronouns, from &lt;a href=&quot;https://astrabun.com/projects/sonasky/&quot; target=&quot;_blank&quot;&gt;@adorable.mom&lt;/a&gt;&#39;s &lt;a href=&quot;https://bsky.app/profile/pronouns.adorable.mom&quot; target=&quot;_blank&quot;&gt;pronoun labeler&lt;/a&gt;. Then, the third is from SonaSky (what a surprise, I labeled myself &amp;quot;Rabbit&amp;quot;! Who could have guessed?!)&lt;/em&gt;&lt;/p&gt;
&lt;h4&gt;how it works&lt;/h4&gt;
&lt;p&gt;On the backend, there are a few components working to run this labeler. At the core is Bluesky&#39;s &lt;a href=&quot;https://github.com/bluesky-social/ozone&quot; target=&quot;_blank&quot;&gt;Ozone&lt;/a&gt;, a &amp;quot;web interface for labeling content in atproto / Bluesky&amp;quot;. I used this to convert the sonasky Bluesky account into a labeler service service and announce it to the network. This tool is great for manually reviewing and adding labels, but I didn&#39;t want to have to assign labels by hand for everyone who wanted to use this.&lt;/p&gt;
&lt;p&gt;That&#39;s why, next, I wrote a TypeScript bot (running in a Docker container) that subscribes to the Bluesky firehose and watches for any like/unlike events. If the event is a &amp;quot;like&amp;quot; event, there is a filter to check if the post being liked was made by the sonasky account, and if the post text starts with &amp;quot;Species: &amp;quot;. It&#39;ll make sense why in a moment. The unlike events do not seem to contain details on the account that made the post that&#39;s being unliked, but they do contain the unliking user&#39;s DID + a unique ID that matches an ID in the &amp;quot;like&amp;quot; event. So when the user performs the initial like, a record is added to a Postgres database with the unique ID and some other metadata like timestamp, user DID, and what species label picked.&lt;/p&gt;
&lt;p&gt;So, why &amp;quot;Species: &amp;quot; as a prefix? I wanted maintaining this and adding new labels to be as easy and low-effort for myself as possible, because I kenw if folks did decide to use this service, I did not create all the labels I&#39;d need at the start. So I can easily define a new label by creating a post as the sonasky account in the format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;Species: &amp;lt;species name but no hyphens&amp;gt;
// Optional comments for making searching posts easier.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once the post is created, all I have to do is like and then unlike it to create the label. The Typescript bot listening for likes will pick it up, see that the label doesn&#39;t exist yet on the labeler, and creates a new label with a default display name and description (display name is the species name as entered with capitalization matching the Bluesky post, and description is &amp;quot;This user&#39;s fursona is a(n) ...&amp;quot;. The &amp;quot;n&amp;quot; is added dynamically if the species starts with a vowel. Fancy~). Users can like the post that contains a species label they want, and it&#39;ll be applied almost immediately. They can then unlike it to remove that label.&lt;/p&gt;
&lt;p&gt;I specifically note to avoid using hyphens in the post because Bluesky label IDs cannot include spaces (or underscores, it turns out, based on my experience/debugging). I find/replace all spaces in the species name with hyphens to deal with this.&lt;/p&gt;
&lt;p&gt;I admit, there&#39;s probably easier ways I could have done this than forbid hyphens. I suppose I could have just removed the spaces for the label ID and then hyphens wouldn&#39;t interfere. Generally speaking, I felt okay with this workaround because... well for one I didn&#39;t think about just removing all spaces entirely for the ID field, that would have been smart, but secondly because not every species has a hyphen in its common name. Things are fairly flexible when it comes to including a hyphen in a common name, like &amp;quot;red-tailed hawk&amp;quot; or &amp;quot;blue-ringed octopus&amp;quot;; these are included for readability rather than a strict rule though. (If we&#39;re talking scientific names of species, then we get &lt;span class=&quot;fun-em&quot;&gt;really&lt;/span&gt; strict; the International Code of Zoological Nomenclature (ICZN) has some &lt;a href=&quot;https://code.iczn.org/formation-and-treatment-of-names/article-32-original-spellings/?frame=1#art-32-5&quot; target=&quot;_blank&quot;&gt;very specific rules about when hyphens can be used, if at all — in most cases, not&lt;/a&gt; — in scientific names).&lt;/p&gt;
&lt;p&gt;Anyway, if a species&#39;s common name is written with a hyphen, I&#39;ll typically just go into the Ozone UI, pull up the label JSON data, and manually add it back in myself.&lt;/p&gt;
&lt;h4&gt;using the labeler and making that easier&lt;/h4&gt;
&lt;p&gt;I don&#39;t think I mentioned yet that I did most of this work between 9pm on a Wednesday through 2am on a Thursday (I think; it was late, time is blurry). I made some labels for some common/popular species based on &lt;a href=&quot;https://furscience.com/research-findings/fursonas/3-1-species-popularity/&quot; target=&quot;_blank&quot;&gt;FurScience&#39;s most popular species&lt;/a&gt; graph, thinking &amp;quot;this&#39;ll do for now&amp;quot; and promptly falling asleep.&lt;/p&gt;
&lt;p&gt;I woke up the next day to find... like 5 people maybe, max, including myself, used it. Not quite the &amp;quot;this blew up&amp;quot; story you might have expected, based on how I built that up. So I went to work. Then I got home, and &lt;em&gt;that&#39;s&lt;/em&gt; when I noticed all my notifications! Lots of requests for new species. It was really exciting to see so much enthusiasm right at the start of this project.&lt;/p&gt;
&lt;p&gt;I spent the evening catching up on every request I saw in the replies to the announcement post, and very quickly there were a &lt;em&gt;lot&lt;/em&gt; more labels. So much so that it was actually kind of hard to find existing ones you knew you wanted. At first, I had made a Bluesky feed (using Skyfeed) containing just posts starting with &amp;quot;Species: &amp;quot; and sorted by popularity, but this too was difficult to browse/search.&lt;/p&gt;
&lt;p&gt;So, I quickly threw together a couple of new components to this contraption. First, any time a new label was added by the Typescript bot, dump the entire label service out to JSON, and store on disk. Then, using a very-quickly-thrown-together React web app (React because I knew I could make something SUPER fast and simple, and also that looked nice using &lt;a href=&quot;https://mui.com/&quot; target=&quot;_blank&quot;&gt;Material UI&lt;/a&gt;), display that data in a table (&lt;a href=&quot;https://github.com/gregnb/mui-datatables&quot; target=&quot;_blank&quot;&gt;mui-datatables&lt;/a&gt;, to be precise) with a search bar.&lt;/p&gt;
&lt;p&gt;I tweaked this for a bit, eventually adjusted the theme to be in &amp;quot;dark mode&amp;quot;, and eventually added some parsing in for the descriptions so I could add metadata-like fields to the table without having to actually modify the JSON schema that Ozone requires. For example, &lt;code&gt;&amp;quot; ... [Category: Mustelid] ...&amp;quot;&lt;/code&gt; in the description will add a key to the array of objects feeding the datatable, like &lt;code&gt;{... category: &amp;quot;Mustelid&amp;quot;}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To browse sonasky labels, see &lt;a href=&quot;https://sonasky-browse.bunnys.ky/&quot; target=&quot;_blank&quot;&gt;https://sonasky-browse.bunnys.ky/&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;conclusion&lt;/h4&gt;
&lt;p&gt;This project was a really fun time to make, and a great learning experience. I ended up having to learn quite a bit about the AT Protocol and how to interact with it, and I appreciated getting to think through how to design this so it was easy to use and easy to maintain.&lt;/p&gt;
&lt;p&gt;Now, about a week after creation (at time of writing), more than 1,000 users have sona labels on their accounts! I am so happy to see folks using this, and even more happy to see all the different (almost entirely positive) responses and posts about this tool. Especially over the first few days, every time I saw someone like a species post or request a new one, I&#39;d check out their account, and a lot of people had posted some really nice comments about the labeler and what it meant to them. I&#39;m most thankful for this opportunity to help continue fostering the furry community presence on Bluesky. (Maybe that sounds a bit grandiose, but hey, just let me have this. I&#39;m proud of a thing I did!)&lt;/p&gt;
&lt;h4&gt;Updates&lt;/h4&gt;
&lt;h5&gt;&lt;a name=&quot;update-2024-08-21&quot;&gt;&lt;/a&gt;Update 2024-08-21&lt;/h5&gt;
&lt;p&gt;Made some updates to the code to make the bot a bit more resilient to network issues.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For this update, I switched the library I was using to listen to the Bluesky firehose from &lt;code&gt;atproto-firehose&lt;/code&gt; to &lt;code&gt;@skyware/firehose&lt;/code&gt; (shoutout to &lt;a href=&quot;https://bsky.app/profile/did:plc:b3pn34agqqchkaf75v7h43dk&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;@adorable.mom&lt;/a&gt; for using it in their pronouns labeler, which I saw they had the code up for!).&lt;/p&gt;
&lt;p&gt;The skyware library has a nice feature to resume the firehose from a given checkpoint; @adorable.mom had a nice implementation to store a checkpoint of the cursor value every minute. I updated sonasky to store the cursor every 60 seconds and resume from the most recent checkpoint on startup. Then, on any errors reading the firehose, just &lt;s&gt;crash&lt;/s&gt; exit the program and docker will restart it and pick up where it left off, rather than, oh I dunno, sitting idle for 12 hours and missing a ton of label assignments. Who would let &lt;em&gt;that&lt;/em&gt; happen? Surely not me... *sweats*&lt;/p&gt;
&lt;p&gt;Anyway, code cleanup is going alright. Need to do a little bit more tidying, and I hope to publish what I&#39;ve got soon (much in the spirit of @adorable.mom&#39;s pronouns one, because that really helped me with the whole losing-connection-to-firehose-issue).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/sonasky/#update-2024-08-21&quot;&gt;Permalink to this update&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;&lt;a name=&quot;update-2024-09-05&quot;&gt;&lt;/a&gt;Update 2024-09-05&lt;/h5&gt;
&lt;p&gt;Bunch of small updates made over the last week or two! The entirety of Brazil joined Bluesky, so things got slow for a bit! To keep things feeling welcome and inclusive, I set up &lt;a href=&quot;https://github.com/astrabun/sonasky-labels-localization&quot; target=&quot;_blank&quot;&gt;sonasky-labels-localization&lt;/a&gt;, a repo to coordinate translating the English labels/descriptions into Brazilian Portuguese (and, hopefully, more languages in the future!) Thank you to the couple of folks who have been helping with translation so far. At the time of writing, about 60% of the labels are translated into pt-BR!&lt;/p&gt;
&lt;p&gt;I added in some logic to store the human readable timestamp of the cursor position to the SonaSky browse site (as well as relative time using dayjs), and I added logic to the bot to check the delay time every 10 minutes and if it ever slips past a 5 minute delay, update the display name of the Bluesky profile (also, no matter what, the profile description gets updated with the cursor position/delay details).&lt;/p&gt;
&lt;p&gt;I also added a table to the database to store the post links so the &amp;quot;Go to Bluesky&amp;quot; links on SonaSky browse can go directly to them rather than using a mostly-functional Bluesky search.&lt;/p&gt;
&lt;p&gt;Finally, I tidied up the code to be good-enough. There&#39;s some stuff that&#39;s hardcoded like the profile description, but whatever. &lt;a href=&quot;https://github.com/astrabun/sonasky&quot; target=&quot;_blank&quot;&gt;It&#39;s up on Github now!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/sonasky/#update-2024-09-05&quot;&gt;Permalink to this update&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;&lt;a name=&quot;update-2024-09-15&quot;&gt;&lt;/a&gt;Update 2024-09-15&lt;/h5&gt;
&lt;p&gt;Apparently, there&#39;s a limit to how much data you can send to Bluesky in the label definitions field. I get &amp;quot;Error: request entity too large&amp;quot; whenever I try to push new/updated label definitions, which is a problem.&lt;/p&gt;
&lt;p&gt;I&#39;ve opened a bug with Bluesky to see if anyone can look into it:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ozone/Labeler Update Fails with &amp;quot;Request entity too large&amp;quot; when adding large number of labels/localizations &lt;a href=&quot;https://github.com/bluesky-social/atproto/issues/2803&quot; target=&quot;_blank&quot;&gt;#2803&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/sonasky/#update-2024-09-15&quot;&gt;Permalink to this update&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;&lt;a name=&quot;update-2024-10-25&quot;&gt;&lt;/a&gt;Update 2024-10-25&lt;/h5&gt;
&lt;p&gt;After hitting that maximum data size limit a few more times, I split SonaSky into two labelers because the biggest category of labels by far was Pokemon. The same bot controls both labellers, and the definition file for the labels denotes which labeller serves that label.&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/MNN60X7UZy-4140.webp 4140w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/MNN60X7UZy-4140.jpeg&quot; alt=&quot;SonaSky &amp;quot;v2&amp;quot; Diagram showing that there are two labelers being controlled by the same bot&quot; width=&quot;4140&quot; height=&quot;4245&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/sonasky/#update-2024-10-25&quot;&gt;Permalink to this update&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;read more&lt;/h4&gt;
&lt;p&gt;&lt;a href=&quot;https://bsky.social/about/blog/03-12-2024-stackable-moderation&quot; target=&quot;_blank&quot;&gt;Bluesky’s Stackable Approach to Moderation&lt;/a&gt; (March 12, 2024, by The Bluesky Team)&lt;/p&gt;
&lt;p&gt;GitHub: &lt;a href=&quot;https://github.com/bluesky-social/ozone&quot; target=&quot;_blank&quot;&gt;bluesky-social/ozone&lt;/a&gt;&lt;/p&gt;
&lt;div id=&quot;c_widget&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://astrabun.com/assets/js/comments.js&quot;&gt;
&lt;/script&gt;
</content>
  </entry>
  <entry>
    <title>Welcome!</title>
    <link href="https://astrabun.com/blog/2024/08/17/welcome/" />
    <updated>2024-08-17T16:00:00Z</updated>
    <id>https://astrabun.com/blog/2024/08/17/welcome/</id>
    <content type="html">&lt;p&gt;I&#39;ve redone my website a bit! This time around, it&#39;s taking a trip back to the early 2000s, at least in terms of aesthetic.&lt;/p&gt;
&lt;p&gt;Wiped out my old blog as well bc I wasn&#39;t really happy with the post quality. Felt too fake.&lt;/p&gt;
&lt;p&gt;Short post.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;git add . &amp;amp;&amp;amp; git commit -m &amp;quot;update&amp;quot; &amp;amp;&amp;amp; git push
&lt;/code&gt;&lt;/pre&gt;
</content>
  </entry>
  <entry>
    <title>CritterWeb Webring</title>
    <link href="https://astrabun.com/projects/critterweb/" />
    <updated>2024-08-21T00:00:00Z</updated>
    <id>https://astrabun.com/projects/critterweb/</id>
    <content type="html">&lt;!-- ---
layout: &#39;2026_05&#39;
title: &quot;CritterWeb Webring - projects&quot;
permalink: /projects/critterweb/
date: 2024-08-21
--- --&gt;
&lt;h3&gt;project: CritterWeb Webring&lt;/h3&gt;
&lt;p&gt;CritterWeb is a furry-themed webring that I built using Jekyll. I wrote about the experience of making it &lt;a href=&quot;https://astrabun.com/blog/2024/08/22/webring/&quot;&gt;in a blog post&lt;/a&gt;!&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>Rabbit Makes Webring in the Year 2024??</title>
    <link href="https://astrabun.com/blog/2024/08/22/webring/" />
    <updated>2024-08-22T02:30:00Z</updated>
    <id>https://astrabun.com/blog/2024/08/22/webring/</id>
    <content type="html">&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/5sc7Kpc1vY-1361.webp 1361w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/5sc7Kpc1vY-1361.jpeg&quot; alt=&quot;Article header image - Old webring.org header image with a bunny peaking out from the bottom-right corner&quot; width=&quot;1361&quot; height=&quot;747&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=B4LFYs3VpxY&quot; target=&quot;_blank&quot;&gt;In my thirst for internet-of-yesteryear-vibes, I made a webring&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;What&lt;/h3&gt;
&lt;p&gt;A webring is a collection of websites that are linked together in a circular structure, where each site includes a link to the next site in the ring. This format was popular in earlier days of the internet as a way for groups of people with similar themed websites to connect and share. It&#39;s a way to discover new websites, without all that newfangled &amp;quot;Ess-Ee-Ohh&amp;quot; (SEO) Google garbage.&lt;/p&gt;
&lt;p&gt;Webrings still exist, but I don&#39;t really hear about them much anymore.&lt;/p&gt;
&lt;h3&gt;Why&lt;/h3&gt;
&lt;p&gt;When webrings were more popular, I wasn&#39;t old enough to appreciate them, and I certainly would not have known enough how to make a website (at least not one I would deem worthy of being in a webring). I think they allow for real connection online, which I especially value nowadays in this hyperconnected, hypercommodified version of the internet. It&#39;s a slower, more intentional way to connect, where the emphasis isn&#39;&#39;&#39;t on clicks, likes, or shares, but on genuine interest. This also satisfies an intense nostalgia I have for old internet.&lt;/p&gt;
&lt;p&gt;The charm, it seems to me, is in the journey; clicking from one site to the next, you never quite know what you&#39;ll find. It could be a fan page for your favorite TV show, a personal blog full of unfiltered thoughts, or a treasure trove of art. It&#39;s exploration, with no algorithms - just pure, uncurated discovery. For me, personal websites are a space that values creativity over conformity, where we can celebrate our shared interests and maybe even inspire each other along the way, and a webring to connect these silos feels like the perfect, era-approprirate way to do so.&lt;/p&gt;
&lt;p&gt;So, I&#39;m making up for lost time. Time to... &lt;em&gt;&lt;strong&gt;start my own webring&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;When&lt;/h3&gt;
&lt;p&gt;2024. Yep.&lt;/p&gt;
&lt;h3&gt;Who&lt;/h3&gt;
&lt;p&gt;Me, silly.&lt;/p&gt;
&lt;h3&gt;How&lt;/h3&gt;
&lt;p&gt;I&#39;m getting to that!&lt;/p&gt;
&lt;p&gt;I wanted to keep things simple. Or at least &amp;quot;simple&amp;quot; insofar as the following criteria is concerned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Minimal JavaScript&lt;/li&gt;
&lt;li&gt;Static Site Generation (mainly so I can host it on Github Pages or move it elsewhere in the future)&lt;/li&gt;
&lt;li&gt;Easy to Update
&lt;ul&gt;
&lt;li&gt;to add new sites to a webring&lt;/li&gt;
&lt;li&gt;to add new webrings to the system&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Out of scope: OPML/RSS feeds. Maybe that&#39;s something I&#39;ll want to revisit later, but for now, I just want a directory of sites that I can click through in a web browser.&lt;/p&gt;
&lt;p&gt;I briefly explored a few existing solutions, including:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/k3rs3d/ringfairy&quot; target=&quot;_blank&quot;&gt;ringfairy&lt;/a&gt; - Rust-based webring generator&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mldangelo/open-webring&quot; target=&quot;_blank&quot;&gt;open-webring&lt;/a&gt; - JavaScript webring software&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But neither of these did quite what I wanted. I&#39;m already using &lt;a href=&quot;https://jekyllrb.com/&quot; target=&quot;_blank&quot;&gt;Jekyll&lt;/a&gt; to build my own site, and I&#39;ve been getting pretty familiar with it, so I wondered if I could use that somehow. With a bit of work, it turns out I could.&lt;/p&gt;
&lt;p&gt;The following are bits and pieces of the Jekyll site with some notes on why they&#39;re there and what they&#39;re doing. To explore on your own, you could always go check out the &lt;a href=&quot;https://github.com/astrabun/critterweb.net&quot; target=&quot;_blank&quot;&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;_data/sites.yml&lt;/code&gt; - Simple data file defining any sites that belong to any webrings within this generated site. For example, my site:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;- name: Astra Bun
  link: &amp;quot;https://astrabun.com&amp;quot;
  description: |
    A bun on the internet!
  rings:
    - critters
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This file is meant to be super easy to update; if someone is joining the webring, just create a new object in the list with a name, link, and description, and set rings to a list of ring IDs (slugs). If a user is meant to be on multiple rings (there aren&#39;t multiple on this service, at least not at the time of writing), then additional IDs can be added to their rings list.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;rings/&amp;lt;ring-slug&amp;gt;.md&lt;/code&gt; - File to store webring metadata in. For the &amp;quot;critters&amp;quot; web ring, it&#39;s &lt;code&gt;rings/critters.md&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;---
slug: &#39;critters&#39;
name: &#39;The Internet Critters Webring&#39;
description: &#39;Webring for Internet Critters&#39;
layout: ring
---
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not much to say here - just some basic metadata.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;_layouts/rings.html&lt;/code&gt; - Layout file for rendering the webring info page (and also the JSON of the ring members??)&lt;/p&gt;
&lt;p&gt;This was probably the trickiest part of the process. This layout handles both rendering an HTML info page on what the ring is, who the members are, and some sample code to use as a member. There&#39;s some Liquid magic that handles the conditional output:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;
{% if page.url contains &#39;.json&#39; %}
{% include generate_ring_json.json slug=page.slug %}
{% else %}
...

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;generate_ring_json.json&lt;/code&gt; is itself a Liquid file designed to filter the list of sites to only those with the current webring slug present and render an object that contains that array. I couldn&#39;t find a very graceful way to do this, so there&#39;s some really nasty string interpolation stuff happening to cobble together the JSON.&lt;/p&gt;
&lt;p&gt;The rings layout page also contains reference to &lt;code&gt;_includes/display_webring.md&lt;/code&gt; which generates the sample code for including the webring navigation on a site. There&#39;s a few Liquid if/else conditions in there so that I could also use the same component to render a sample of what the navigation looks like, and also what it looks like when a website not in the webring uses it. There&#39;s a bit of code duplication in this file, but I decided I just don&#39;t care enough to worry about it. The duplication is really just to provide sample outputs simulating if the current site WAS or WAS NOT in the webring. It doesn&#39;t really matter if it is &amp;quot;correct&amp;quot; because this site will not be in the webring. Also, my goal was to spin this up as fast as possible, so, get off my back or whatever.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;api/rings.json&lt;/code&gt; - A Liquid file to provide a JSON-formatted representation of all avaiable webrings (metadata only).&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;---
layout: none
---
{% assign data = site.rings | jsonify %}
{% assign keys_to_remove = &amp;quot;content,output,path,relative_path,date,collection,excerpt,categories,next,tags,previous,draft,layout,ext,id&amp;quot; | split: &amp;quot;,&amp;quot; %}
{% assign filtered_data = data | ring_remove_keys: keys_to_remove %}
{% assign object_data = filtered_data | ring_array_to_object %}
{{ object_data }}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;api/rings/&amp;lt;slug&amp;gt;.json&lt;/code&gt; (or in this case, &lt;code&gt;api/rings/critters.json&lt;/code&gt;) - Finishes handling the JSON formatting for a given ring.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;---
layout: ring
permalink: /api/rings/critters.json
slug: critters
---

{% assign page.url = &amp;quot;/api/rings/critters.json&amp;quot; %}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This works with a Ruby plugin and the condition in the ring layout to render the ring data in JSON.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;code&gt;_config.yml&lt;/code&gt; - a few notable config options to tie the last of this together&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;# ...
collections:
  rings:
    output: true
    permalink: /:collection/:slug
defaults:
  - scope:
      path: &amp;quot;&amp;quot;
      type: rings
    values:
      layout: ring
# ...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Mainly, the collection for rings is defined here, and we&#39;re able to set a default layout for the rings. Not much else to mention.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;There&#39;s a few small, custom Ruby plugins (some you&#39;ve probably seen mentioned in code blocks above) written to do some data massaging, and one to help with conditionally using the JSON format of the ring page. These aren&#39;t too interesting, so I&#39;m not going to spend time on them.&lt;/p&gt;
&lt;h3&gt;Where&lt;/h3&gt;
&lt;p&gt;I&#39;m putting the ring &lt;a href=&quot;https://critterweb.net/rings/critters&quot; target=&quot;_blank&quot;&gt;here, on critterweb.net&lt;/a&gt;. I think I&#39;ve built this in such a way that additional webrings can be hosted on this domain in the future, but for now, it&#39;s just the one! Interested in joining? The critter ring is aimed to be for furries, especially furries with websites that have similar aeshetics/small-web designs, so let me know if you&#39;d like to join, either in the comments, or on &lt;a href=&quot;https://bsky.app/profile/astrabun.com&quot; target=&quot;_blank&quot;&gt;Bluesky&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;This project, albeit challenging at times trying to wrestle with Liquid, was a blast from start to finish, not just because it let me flex my Jekyll muscles but because it felt like a tribute to the simpler, more personal days of the internet. Back before everything was dominated by AI and endless scrolling, the internet seemed to have more magical spaces - small, interconnected, and full of personality.&lt;/p&gt;
&lt;p&gt;It also gives me another chance to connect with the furry community online, which is so important to me. Furry is a hobby for me, but it&#39;s also a community that I&#39;ve always found warmth and creativity in. This webring is a small way for me to contribute back to that, to hopefully connect with other furs and help us stay connected in our own unique corner of the web.&lt;/p&gt;
&lt;p&gt;Thank you for reading as I went on this little journey down internet memory lane.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Also, check the footer of my website! There it is, the little navigation thingy!&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;UPDATES&lt;/h3&gt;
&lt;h4&gt;&lt;a name=&quot;update-remove-js-from-member-site&quot;&gt;&lt;/a&gt;2024-08-23&lt;/h4&gt;
&lt;p&gt;After getting some sleep, I realized there&#39;s no need to force all members to do their own JS implementation (especially if they prefer not to have much JS on their site), so instead I&#39;ve updated the site to handle linking to next/previous sites.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;
&amp;lt;div id=&amp;quot;critter-webring-nav&amp;quot;&amp;gt;
    &amp;lt;p&amp;gt;The Internet Critters Webring&amp;lt;/p&amp;gt;
    &amp;lt;div&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;https://critterweb.net/rings/critters?name=SimulatedSiteName&amp;amp;to=prev&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;previous&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;https://critterweb.net/rings/critters&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;info&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
        &amp;lt;span&amp;gt;&amp;lt;a href=&amp;quot;https://critterweb.net/rings/critters?name=SimulatedSiteName&amp;amp;to=next&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;next&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes it a lot easier for folks to join than having to fiddle with JavaScript, but still leaves room for custom styling per site if desired! A simple previous/next link where you pass in your site name and the direction you want seems much simpler.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/blog/2024/08/22/webring/#update-remove-js-from-member-site&quot;&gt;[Permalink to this update]&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Read More&lt;/h3&gt;
&lt;p&gt;I found these resources helpful along this journey:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&amp;quot;&lt;a href=&quot;https://gist.github.com/MichaelCurrin/f8d908596276bdbb2044f04c352cb7c7&quot; target=&quot;_blank&quot;&gt;Jekyll - how to build a REST API&lt;/a&gt;&amp;quot; - Gist on Github with some helpful notes on JSON/REST API in Jekyll&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/Webring&quot; target=&quot;_blank&quot;&gt;https://en.wikipedia.org/wiki/Webring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://indieweb.org/webring&quot; target=&quot;_blank&quot;&gt;https://indieweb.org/webring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://hover.blog/what-ever-happened-to-webrings/&quot; target=&quot;_blank&quot;&gt;What Ever Happened To Webrings?&lt;/a&gt; (blog post on Hover, a DNS registrar; I&#39;ve not used their services, but I liked this little blog post)&lt;/li&gt;
&lt;li&gt;[&lt;em&gt;NEW&lt;/em&gt;] &amp;quot;&lt;a href=&quot;https://cascading.space/post/what-if-webrings-but-static-hosting/&quot; target=&quot;_blank&quot;&gt;What if Webrings, but Static Hosting?&lt;/a&gt;&amp;quot; by Cascade (member of the critters webring! published 2024-08-24T05:26:19.571Z)&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
  <entry>
    <title>Fairs are for seeing bunnies</title>
    <link href="https://astrabun.com/blog/2024/08/24/fair/" />
    <updated>2024-08-24T16:00:00Z</updated>
    <id>https://astrabun.com/blog/2024/08/24/fair/</id>
    <content type="html">&lt;p&gt;I don&#39;t actually have much to say on this. Just wanted to cross-post this to the blog. Bnuy good.&lt;/p&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;blockquote class=&quot;bluesky-embed&quot; data-bluesky-uri=&quot;at://did:plc:nkleu4mgtlxpsfwkdm6otsqu/app.bsky.feed.post/3l2id227xfw2e&quot; data-bluesky-cid=&quot;bafyreidm2oqfjbztxpnusr4px5t4ubsoyd2akm372hk2d6q4l64tnc64yq&quot;&gt;&lt;p lang=&quot;en&quot;&gt;Fairs are for seeing bunnies
&lt;/p&gt;&lt;p&gt;#photography #rabbit #rabbits&lt;br&gt;&lt;br&gt;&lt;a href=&quot;https://bsky.app/profile/did:plc:nkleu4mgtlxpsfwkdm6otsqu/post/3l2id227xfw2e?ref_src=embed&quot;&gt;[image or embed]&lt;/a&gt;&lt;/p&gt;— Astra (&lt;a href=&quot;https://bsky.app/profile/did:plc:nkleu4mgtlxpsfwkdm6otsqu?ref_src=embed&quot;&gt;@astrabun.com&lt;/a&gt;) &lt;a href=&quot;https://bsky.app/profile/did:plc:nkleu4mgtlxpsfwkdm6otsqu/post/3l2id227xfw2e?ref_src=embed&quot;&gt;Aug 24, 2024 at 2:42 PM&lt;/a&gt;&lt;/blockquote&gt;&lt;script async=&quot;&quot; src=&quot;https://embed.bsky.app/static/embed.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;&lt;p&gt;&lt;/p&gt;
&lt;/div&gt;</content>
  </entry>
  <entry>
    <title>sonasky ref</title>
    <link href="https://astrabun.com/projects/sonasky-ref/" />
    <updated>2025-01-11T00:00:00Z</updated>
    <id>https://astrabun.com/projects/sonasky-ref/</id>
    <content type="html">&lt;h3&gt;project: sonasky ref&lt;/h3&gt;
&lt;h4&gt;SonaSky REF&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Furry ref-sheet hosting using your Bluesky account (AT Protocol)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/hlb55bzxRi-1200.webp 1200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/hlb55bzxRi-1200.jpeg&quot; alt=&quot;&quot; width=&quot;1200&quot; height=&quot;630&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/sonasky-ref&quot;&gt;permalink&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;about&lt;/h4&gt;
&lt;p&gt;My previous project was &lt;a href=&quot;https://bsky.app/profile/sonasky.bsky.social&quot; target=&quot;_blank&quot;&gt;SonaSky&lt;/a&gt;, a Bluesky Labeler providing fursona species account labels for furry users on the platform. Folks seem to like that, with over 20,000 furries applying various species labels to their profiles. You can read more about that &lt;a href=&quot;https://astrabun.com/projects/sonasky&quot;&gt;here, if you want&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/5MDlwLjIQb-1308.webp 1308w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/5MDlwLjIQb-1308.jpeg&quot; alt=&quot;A screenshot of the SonaSky website, with text reading: &amp;quot;Woah! 20,059 users are using SonaSky, with 39,688 labels assigned! That&#39;s an average of 1.98 labels per user.&amp;quot;&quot; width=&quot;1308&quot; height=&quot;612&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;With this large of an audience comes many, many requests for new label definitions (&amp;quot;The species xyz is not listed, can you create a label for it?&amp;quot;) But Bluesky has a cap on the payload size for labeller definitions, and SonaSky hit it... several times.&lt;/p&gt;
&lt;p&gt;After months of trying to figure out how to accomodate for a near-infinite number of species possibilities, I was hitting a wall. How could I remove myself from a position where I have to decide what labels get to exist and which don&#39;t because of an arbitrary data size restriction?&lt;/p&gt;
&lt;p&gt;Well, after months and months of planning, brainstorming, and learning, I am very happy to present: &lt;a href=&quot;https://ref.sonasky.app/&quot; target=&quot;_blank&quot;&gt;SonaSky Ref&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/rUStgHXSez-1280.webp 1280w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/rUStgHXSez-1280.jpeg&quot; alt=&quot;A screenshot of the SonaSky Ref homepage, showing a text input box asking for a Bluesky handle.&quot; width=&quot;1280&quot; height=&quot;720&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;The goal for SonaSky Ref is to provide a way for furries to store information about their characters that isn&#39;t limited by which labels are available on SonaSky. It allows for more specificity (text input for species name, text input for description), AND it provides a way for furries to host their ref sheet information.&lt;/p&gt;
&lt;p&gt;The best part? It&#39;s all a part of your Bluesky account. Like, the data literally lives in the same place as your Bluesky profile. AT Protocol, baybeeeeeee~&lt;/p&gt;
&lt;div style=&quot;display: flex; flex-direction: row; gap: 1rem; max-width: 100%; width: 100%;&quot;&gt;
    &lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/QWsbq7We49-1280.webp 1280w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/QWsbq7We49-1280.jpeg&quot; style=&quot;width: 100%; height: auto; object-fit: contain;&quot; alt=&quot;Character selection&quot; width=&quot;1280&quot; height=&quot;720&quot;&gt;&lt;/picture&gt;
    &lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/NuSnL3YWfK-776.webp 776w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/NuSnL3YWfK-776.jpeg&quot; style=&quot;width: 100%; height: auto; object-fit: contain;&quot; alt=&quot;PDS repo collections&quot; width=&quot;776&quot; height=&quot;538&quot;&gt;&lt;/picture&gt;
&lt;/div&gt;
&lt;p&gt;You can build a ref sheet that contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name&lt;/li&gt;
&lt;li&gt;Pronouns&lt;/li&gt;
&lt;li&gt;Species&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;li&gt;Colors&lt;/li&gt;
&lt;li&gt;Ref Sheet Image&lt;/li&gt;
&lt;li&gt;Alternate Ref Sheet Image&lt;/li&gt;
&lt;li&gt;A few miscellaneous tags (like &amp;quot;NSFW&amp;quot;, or &amp;quot;OK to draw without asking&amp;quot;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/2McVCohrXj-1280.webp 1280w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/2McVCohrXj-1280.jpeg&quot; alt=&quot;&quot; width=&quot;1280&quot; height=&quot;720&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;h4&gt;how to use it&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;visit the website and sign in with your Bluesky account&lt;/li&gt;
&lt;li&gt;on the dashboard, click &amp;quot;Add Character&amp;quot;&lt;/li&gt;
&lt;li&gt;fill out the form and click &amp;quot;save&amp;quot;
&lt;ul&gt;
&lt;li&gt;to include a ref sheet image, have a post on Bluesky where the first (or only) image in the post is your ref sheet. Then, paste the URL to the post in the box (it&#39;ll auto-format the link as the at:// format for you)&lt;/li&gt;
&lt;li&gt;to add colors, click the &amp;quot;add color&amp;quot; button, enter a hex code or select a color, and optionally add a label for what the color is used for.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;click &amp;quot;Characters&amp;quot; on the dashboard to manage (update/delete) existing characters saved to your account&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/4LEolwI_MI-1144.webp 1144w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/4LEolwI_MI-1144.jpeg&quot; alt=&quot;&quot; width=&quot;1144&quot; height=&quot;500&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;h4&gt;how to see other people&#39;s characters/ref sheets&lt;/h4&gt;
&lt;p&gt;When you&#39;re on a user&#39;s Bluesky profile page, and the url looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;https://bsky.app/profile/astrabun.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Change the &amp;quot;b&amp;quot; in &amp;quot;bsky&amp;quot; to &amp;quot;s&amp;quot;, so the url looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;code-wrap-style&quot;&gt;https://ssky.app/profile/astrabun.com
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you will be redirected to the appropriate page on &lt;code&gt;ref.sonasky.app&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Example: &lt;a href=&quot;https://ref.sonasky.app/profile/did:plc:nkleu4mgtlxpsfwkdm6otsqu/3lfgbb2miec2d&quot; target=&quot;_blank&quot;&gt;My ref sheet!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can also type a Bluesky user handle into the homepage on &lt;a href=&quot;https://ref.sonasky.app/&quot; target=&quot;_blank&quot;&gt;https://ref.sonasky.app/&lt;/a&gt; to view if they have any characters in their repo.&lt;/p&gt;
&lt;h4&gt;wrapping up&lt;/h4&gt;
&lt;p&gt;Not too much more to say! I may continue to add other little checkbox/label properties that you can add to the sheet. But for now, please enjoy!&lt;/p&gt;
&lt;h5&gt;Further Reading&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://atproto.com/&quot; target=&quot;_blank&quot;&gt;https://atproto.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://atproto.com/specs/repository&quot; target=&quot;_blank&quot;&gt;https://atproto.com/specs/repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://atproto.com/guides/applications&quot; target=&quot;_blank&quot;&gt;https://atproto.com/guides/applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Source Code&lt;/h5&gt;
&lt;p&gt;Git repo: &lt;a href=&quot;https://github.com/astrabun/sonasky-ref&quot; target=&quot;_blank&quot;&gt;https://github.com/astrabun/sonasky-ref&lt;/a&gt;&lt;/p&gt;
&lt;h5&gt;Updates&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;2025-02-25: Added GitHub link&lt;/li&gt;
&lt;/ul&gt;
&lt;div id=&quot;c_widget&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://astrabun.com/assets/js/comments.js&quot;&gt;
&lt;/script&gt;
</content>
  </entry>
  <entry>
    <title>Kayla Fox Website</title>
    <link href="https://astrabun.com/projects/kaylafox.au/" />
    <updated>2025-04-02T00:00:00Z</updated>
    <id>https://astrabun.com/projects/kaylafox.au/</id>
    <content type="html">&lt;h3&gt;project: &lt;a href=&quot;http://kaylafox.au&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;kaylafox.au&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;[!CAUTION]&lt;/p&gt;
&lt;h3&gt;This project references NSFW/adult content. Please click away if you don&#39;t want to see it.&lt;/h3&gt;
&lt;/blockquote&gt;
&lt;h4&gt;&lt;a href=&quot;http://kaylafox.au&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;kaylafox.au&lt;/a&gt;&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Website for Kayla Fox, a furry artist!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/350aLZDThm-1200.webp 1200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/350aLZDThm-1200.jpeg&quot; alt=&quot;&quot; width=&quot;1200&quot; height=&quot;630&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://astrabun.com/projects/kaylafox.au/&quot;&gt;permalink&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;about&lt;/h4&gt;
&lt;p&gt;Meet Kayla Fox, a talanted artist in the furry community, known for his digital art, 3D modeling and printing, animation, and fursuit creation tools. He specializes in adult furry art, and through Patreon, Kayla Fox offers exclusive content, including early access to art, behind-the-scenes insights, and commissions.&lt;/p&gt;
&lt;p&gt;Enter: Astra - some rabbit on the internet. We&#39;ll get back to him (I mean, me).&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/wjczF4LEBi-1280.webp 1280w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/wjczF4LEBi-1280.jpeg&quot; alt=&quot;&quot; width=&quot;1280&quot; height=&quot;612&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Back in May of 2024, Kayla &lt;a href=&quot;https://www.furaffinity.net/view/56628938/&quot; target=&quot;_blank&quot;&gt;posted the above image on FurAffinity&lt;/a&gt;, titled &amp;quot;Y2Kayla&amp;quot; and with the description:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;late 90&#39;s/ early 2000&#39;s aesthetics are one of my favourite things rn. (and my PSVita)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As a fellow fan of this aesthetic, this was an instant favorite for me! I&#39;ve played around with the layout of my own website to give it elements of mid-aughts flair (e.g., Windows XP styled &amp;quot;windows&amp;quot; like my Bluesky posts embed on the homepage or the nav bar, all styled with &lt;a href=&quot;https://botoxparty.github.io/XP.css/&quot; target=&quot;_blank&quot;&gt;XP.css&lt;/a&gt;), and I love seeing others who appreciate these kinds of designs.&lt;/p&gt;
&lt;p&gt;Anyway, fast forward a few months, and I&#39;m commissioning some art from Kayla. We&#39;re chatting and when it comes time for me to send a reference sheet, I shared the link to &lt;a href=&quot;https://art.astrabun.com/characters/Astra&quot; target=&quot;_blank&quot;&gt;my ref on my website&lt;/a&gt;. Conversation followed, and...&lt;/p&gt;
&lt;div class=&quot;chat-container&quot;&gt;
  &lt;div class=&quot;chat&quot;&gt;
    &lt;span class=&quot;chat-sender&quot;&gt;Kayla Fox&lt;/span&gt;
    &lt;p class=&quot;chat-message&quot;&gt;also is that your own website?&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;chat chat-from-me&quot;&gt;
    &lt;span class=&quot;chat-sender&quot;&gt;astra&lt;/span&gt;
    &lt;p class=&quot;chat-message&quot;&gt;it is yeah!&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;chat&quot;&gt;
    &lt;span class=&quot;chat-sender&quot;&gt;Kayla Fox&lt;/span&gt;
    &lt;p class=&quot;chat-message&quot;&gt;was it done from scratch?&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;chat chat-from-me&quot;&gt;
    &lt;span class=&quot;chat-sender&quot;&gt;astra&lt;/span&gt;
    &lt;p class=&quot;chat-message&quot;&gt;mhmm!&lt;/p&gt;
  &lt;/div&gt;
  &lt;div class=&quot;chat&quot;&gt;
    &lt;span class=&quot;chat-sender&quot;&gt;Kayla Fox&lt;/span&gt;
    &lt;p class=&quot;chat-message&quot;&gt;I&#39;m actually looking for a web designer&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;We talked a bit about the ideas he had for the site, what kinds of features and style he was looking for, what websites inspired him, and so on. With his permission, I&#39;d love to share some of the sites that inspired him because I ALSO really liked these sites:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ne0nbandit.neocities.org/&quot; target=&quot;_blank&quot;&gt;https://ne0nbandit.neocities.org/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;I personally love how colorful and committed this site is to the Vaporwave/Synthwave aesthetic&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://mileshouse.neocities.org/&quot; target=&quot;_blank&quot;&gt;https://mileshouse.neocities.org/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;The music player and the buttons on this site are very cool&lt;/li&gt;
&lt;li&gt;I also love how blobby some of the components are&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kyomakus.online/&quot; target=&quot;_blank&quot;&gt;https://kyomakus.online/&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Windows 98 (or similar era) theme YES&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Kayla sent me some mockup layouts he had made for what he wanted the site to look like, as well as the assets used in these layouts, and I got to work.&lt;/p&gt;
&lt;h4&gt;technology&lt;/h4&gt;
&lt;p&gt;I didn&#39;t want to make the website using some popular JavaScript framework like React because I didn&#39;t think that would properly capture the spirit of making an aughts-retro website, so I opted for a system similar to my own personal website&#39;s - Jekyll.&lt;/p&gt;
&lt;p&gt;For most of what I needed to build this site, HTML + CSS was more than enough. JavaScript is only involved for the interactive components of the page, but we&#39;ll come back to that.&lt;/p&gt;
&lt;p&gt;One of the benefits of using something like Jekyll is that I could define components that I would need to reuse, and abstract them away using the &lt;code&gt;_includes&lt;/code&gt; directory. Items like the bubble icons linking to other sites/platforms are provided within &lt;code&gt;_includes&lt;/code&gt;, then included within the page layout.&lt;/p&gt;
&lt;h5&gt;deployment&lt;/h5&gt;
&lt;p&gt;The Jekyll site and other &amp;quot;helper&amp;quot; scripts (e.g., syncing FA gallery images and post details to site files) source code is stored in a private Git repo. When new, &amp;quot;production&amp;quot;-bound changes make their way into the &lt;code&gt;main&lt;/code&gt; branch, a pipeline for this repo builds the site. Image artifacts (art for the gallery feature) are synced to an Amazon AWS S3 bucket to keep the site build size down, and the rest of the site build is synced to another Git repo. This secondary repo is synced with a Cloudflare Pages application, where new commits on the build-repo trigger new app builds.&lt;/p&gt;
&lt;h4&gt;components and features&lt;/h4&gt;
&lt;h5&gt;music player&lt;/h5&gt;
&lt;p&gt;The music player is a combination of image and text elements with a bit of JavaScript to handle button clicks (pause/play music) and printing the name of the track that&#39;s playing. There&#39;s also code to allow dragging it around the page.&lt;/p&gt;
&lt;p&gt;Turbo Hotwire is used to help with navigating between pages without stopping music playback.&lt;/p&gt;
&lt;h5&gt;comments/guestbook&lt;/h5&gt;
&lt;p&gt;The comments feature is based on &lt;a href=&quot;https://virtualobserver.moe/ayano/comment-widget&quot; target=&quot;_blank&quot;&gt;Ayano (virtualobserver.moe)&#39;s Google Forms/Sheets-based comments system&lt;/a&gt;. The comments widget is styled to look like an old iPod Touch/iPhone Notes App.&lt;/p&gt;
&lt;h5&gt;gallery&lt;/h5&gt;
&lt;p&gt;As mentioned in the &amp;quot;Deployment&amp;quot; section above, there is a disconnect between the site build files and the image files. I tried originally to use direct image links to FurAffinity to show new art pieces, but there seemed to be an issue. Whenever the page would load, the images would NOT load unless you had recently visited the FA post in question in that same browser. If I had to guess, this is thanks to some anti-DDoS protection on FA&#39;s side, or something along those lines. So instead, I have a script that pulls any items from Kayla&#39;s FA gallery that aren&#39;t already downloaded - along with the post link and title - and the post metadata is stored in the Jekyll site&#39;s data directory (in a YAML file), while the images themselves are synced up to an S3 bucket.&lt;/p&gt;
&lt;hr&gt;
&lt;h4&gt;site is live!&lt;/h4&gt;
&lt;p&gt;And now, &lt;a href=&quot;https://www.patreon.com/posts/kaylafox-au-now-120859830&quot; target=&quot;_blank&quot;&gt;in 2025, from Kayla&#39;s Patreon&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;h4&gt;&lt;a href=&quot;http://Kaylafox.au&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;Kaylafox.au&lt;/a&gt; now live!&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;January 26&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Take a break from the corporatized, bland, ad filled and tracked websites of modern-day internet and step back into a time where creativity and fun thrived with &lt;a href=&quot;http://kaylafox.au&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;kaylafox.au&lt;/a&gt; making a revival to the good old days with a fun webpage, my home! Come on over and say hi with the notes system &amp;lt;3&lt;/p&gt;
&lt;p&gt;Check it out at &lt;a href=&quot;https://www.kaylafox.au/&quot; target=&quot;_blank&quot;&gt;kaylafox.au&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;For the full experience I recommend viewing it on desktop.&lt;/p&gt;
&lt;p&gt;Thank you Astra Bun for making my dream become reality &amp;lt;3&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/maCT2Pi9AF-960.webp 960w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/maCT2Pi9AF-960.jpeg&quot; alt=&quot;&quot; width=&quot;960&quot; height=&quot;1280&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Thank you so much to Kayla for allowing me to help make this vision into reality, for taking my commissions, and for being an awesome person to chat with. Special extra thanks to my good friend &lt;a href=&quot;https://toi.sh&quot; target=&quot;_blank&quot;&gt;Gray&lt;/a&gt; for letting me bounce ideas off of him throughout the process and for his suggestion to use Turbo Hotwire.&lt;/p&gt;
&lt;p&gt;Kayla&#39;s Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kaylafox.au&quot; target=&quot;_blank&quot;&gt;Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.patreon.com/kaylafox&quot; target=&quot;_blank&quot;&gt;Patreon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.furaffinity.net/user/rysonanthrodog/&quot; target=&quot;_blank&quot;&gt;Furaffinity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/soxf0x&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;div id=&quot;c_widget&quot;&gt;&lt;/div&gt;
&lt;script src=&quot;https://astrabun.com/assets/js/comments.js&quot;&gt;
&lt;/script&gt;
</content>
  </entry>
  <entry>
    <title>Switched to Eleventy (11ty)</title>
    <link href="https://astrabun.com/blog/2026/01/05/switched-to-11ty/" />
    <updated>2026-01-05T00:00:00Z</updated>
    <id>https://astrabun.com/blog/2026/01/05/switched-to-11ty/</id>
    <content type="html">&lt;p class=&quot;content-img rounded-img&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/Iv2AoL1kUD-1200.webp 1200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/Iv2AoL1kUD-1200.jpeg&quot; alt=&quot;move over, jekyll... 11ty is my *new* static site generator&quot; width=&quot;1200&quot; height=&quot;630&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;Yep, that&#39;s right! But why?&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Why did I switch to 11ty?&lt;/h2&gt;
&lt;h3&gt;Familiarity with Javascript/Typescript&lt;/h3&gt;
&lt;p&gt;I love how configurable Eleventy is using JS. While I am skilling up in Ruby on Rails which is somewhat helping me get better at Ruby, which Jekyll uses, I only need a static site for my personal website. I already have a decent familiarity with JS/TS and being able to configure how builds and templates work using a language I am very comfortable in was super helpful.&lt;/p&gt;
&lt;h3&gt;More content type options (liquid, nunjucks, markdown, html)&lt;/h3&gt;
&lt;p&gt;In addition to MD + HTML with liquid syntax, 11ty supports additional templating languages like nunjucks, which is pretty neat! In general, this can probably be summarized just fine as &amp;quot;11ty is VERY flexible&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Helpful Image Plugin&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;@11ty/eleventy-img&lt;/code&gt; is VERY cool. At build time, images are optimized (or downloaded from remote sources &lt;em&gt;and&lt;/em&gt; optimized). Should be nice and speedy to load images from the site with this, without having to build/maintain my own image optimization pipeline.&lt;/p&gt;
&lt;h3&gt;Try Something New&lt;/h3&gt;
&lt;p&gt;I have an addiction - when I hear about a new framework or tool, I &lt;em&gt;need&lt;/em&gt; to try it out. Eleventy is &lt;em&gt;not&lt;/em&gt; new, but it is new to me, and once I heard about it, I needed to try it. This is probably the reason with the most weight behind it.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;What do you think of Eleventy vs Jekyll? Both have their ups and downs! Comment below or &lt;a href=&quot;https://bsky.app/profile/astrabun.com/post/3mbpshlvyms2m&quot; target=&quot;_blank&quot;&gt;reply on Bluesky&lt;/a&gt;.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>astrabun.com/human.json</title>
    <link href="https://astrabun.com/blog/2026/03/17/human-dot-json/" />
    <updated>2026-03-17T23:22:00Z</updated>
    <id>https://astrabun.com/blog/2026/03/17/human-dot-json/</id>
    <content type="html">&lt;p class=&quot;content-img rounded-img&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/Gl4Y0Wii7C-1200.webp 1200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/Gl4Y0Wii7C-1200.jpeg&quot; alt=&quot;astrabun.com/json - I suppose I could have used bnuy.json... but this serves as my assertion that I am not a robot.&quot; width=&quot;1200&quot; height=&quot;630&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;I was scrolling Bluesky when I came across a &lt;a href=&quot;https://bsky.app/profile/natanael.bsky.social/post/3mhatcne4fs2l&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;post&lt;/a&gt; that had been reposted by &lt;a href=&quot;https://bsky.app/profile/soatok.bsky.social&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;@soatok.bsky.social&lt;/a&gt; about something called &amp;quot;&lt;a href=&quot;https://codeberg.org/robida/human.json&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;human.json&lt;/code&gt;&lt;/a&gt;&amp;quot;. The &lt;code&gt;human.json&lt;/code&gt; protocol description calls out that a ton of internet content today is AI generated slop and posits that we need a way to declare that you are human on the web.&lt;/p&gt;
&lt;p&gt;As someone who is getting more and more tired of the slop filled world we live in, I thought this would make a great addition to my site. &lt;a href=&quot;https://astrabun.com/human.json&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;&lt;code&gt;/human.json&lt;/code&gt;&lt;/a&gt; serves to verify that I am a living creature posting here on the net, and not a large language model. I will, as needed, update my vouches list to include sites of folks I know are not robots (unless their sona is a robot, but y&#39;know what I mean).&lt;/p&gt;
&lt;p&gt;I highly recommend checking out the project and think this would be a neat addition to anyone&#39;s personal site.&lt;/p&gt;
&lt;p&gt;Thank you Soatok for reposting that post that led me to this project (and in general for all of your posts! not that you&#39;ll read this!)&lt;/p&gt;
&lt;p&gt;As a side note, the README for &lt;code&gt;human.json&lt;/code&gt; calls out the &lt;code&gt;/AI&lt;/code&gt; slashpage, linking to &lt;a href=&quot;https://slashpages.net/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;https://slashpages.net/&lt;/a&gt;. Now to explore what other slash-pages I can add to my site...&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>one year til thirty</title>
    <link href="https://astrabun.com/blog/2026/05/04/twenty-nine/" />
    <updated>2026-05-04T04:00:00Z</updated>
    <id>https://astrabun.com/blog/2026/05/04/twenty-nine/</id>
    <content type="html">&lt;p class=&quot;content-img rounded-img&quot;&gt;&lt;picture&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://astrabun.com/img/8IvQtnTBKe-1200.webp 1200w&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://astrabun.com/img/8IvQtnTBKe-1200.jpeg&quot; alt=&quot;opengraph image&quot; width=&quot;1200&quot; height=&quot;630&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;(image by &lt;a href=&quot;https://spadehoof.com/&quot; target=&quot;_blank&quot; rel=&quot;noopener noreferrer&quot;&gt;SpadeHoof&lt;/a&gt;)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;i&#39;m (almost) old?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&#39;s time for my yearly dose of update-the-about-page-to-increase-the-number. Yep, I&#39;m 29 now.&lt;/p&gt;
&lt;p&gt;My 20s have not gone exactly how I expected. Politically, global-health-wise, and personally. But for all the many ups and many downs, one thing doesn&#39;t change - time marches on. Another year has passed. What has happened in that year, for me?&lt;/p&gt;
&lt;p&gt;I went to yet another Anthrocon, seeing friends with whom I&#39;ve developed amazing friendships. I also edited a very fun con video just for myself and those friends. (Maybe I&#39;ll make one for posting publicly in the future, but this one was just for us). I moved to a new state. I mow a lawn now. I have found several creative outlets that have really helped satisfy the urge to create &lt;em&gt;something&lt;/em&gt;. I&#39;ve continued to be invested in watching hockey. I&#39;ve started reading more. I&#39;ve tried to be more intentional with music that I listen to, relying less on algorithms to suggest things &lt;em&gt;at me&lt;/em&gt;. I&#39;ve commissioned some banger art from some amazing artists. I&#39;ve eased back into livestreaming games. I&#39;ve (mostly) migrated away from Windows as an operating system (except for my work PC, on which I can&#39;t escape &lt;s&gt;Microslop&lt;/s&gt; Microsoft). I&#39;ve played some really impactful games, some really funny games, and bonded more with friends in multiplayer games. I&#39;ve tried my best to reduce stress, making some positive changes that, so far, have had some positive impacts in my life. I&#39;ve kissed my partner a &lt;em&gt;whole bunch mwahmwahmwahmwahmwahmwah&lt;/em&gt;. I&#39;ve had a few good cries (&lt;em&gt;&lt;strong&gt;crying and feeling emotions? pretty good ngl&lt;/strong&gt;&lt;/em&gt;).&lt;/p&gt;
&lt;p&gt;At the same time, I also don&#39;t know where the last year went. I feel like I turned 28, blinked, and suddenly I am 29. I don&#39;t feel like it&#39;s been that long. I feel like I still just turned 25 or 26. How much of this is a strange side effect of how compressed 2020-2022 feels in my head, I don&#39;t know. How much of this is that life starts just whizzing by, I also don&#39;t know. What I am pretty confident in is this: I am thankful to be here, I am very thankful for my friends, and I am very, very thankful for my partner.&lt;/p&gt;
&lt;p&gt;The things I know to be core to me haven&#39;t changed even if my aging body has (Note from future Astra editing this: that sounds WAY too dramatic, I&#39;m literally still in my 20s): I still have a deep appreciation for (human made) music and art and the way can affect a person; friends are always there for me and I&#39;m always there for my friends; remember to breathe and survive because that&#39;s how you win.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;changelog&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Monday, May 4, 2026 @ 10:44:08 AM US/Eastern:
&lt;ul&gt;
&lt;li&gt;fix two typos in the paragraph starting &amp;quot;At the same time, ...&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content>
  </entry>
</feed>