<?xml version="1.0" encoding="UTF-8"?>
<!-- GENERATED by tools/build-discovery.py from changelog.html. -->
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>lilharper.dev</title>
  <subtitle>Building things. Helping people. A build log for a site that keeps its receipts.</subtitle>
  <link href="https://lilharper.dev/feed.xml" rel="self"/>
  <link href="https://lilharper.dev/"/>
  <id>https://lilharper.dev/</id>
  <updated>2026-08-22T01:00:00Z</updated>
  <author><name>Harper</name></author>
  <entry>
    <title>The VPS got smaller, and the homepage finally sounds like me</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-08-22:changelog/v2026.08.22a</id>
    <updated>2026-08-22T01:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The front page stopped pretending to be a generic technical portfolio.&lt;/b&gt; It now says what this place actually is: a trans, autistic, ADHD little internet universe full of Hazel, Hilray TV, self-hosting, music, games, writing, Harley and whatever I overbuilt at 2am.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The current-project story matches the current server.&lt;/b&gt; Hazel, the site and Hilray TV are the things running now. Hytale, Enshrouded and Palworld live in one honest archive, with no join details, passwords or fake online indicators.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The infrastructure page was rebuilt around the smaller Debian VPS.&lt;/b&gt; It shows Caddy, the site APIs, Hazel&#x27;s deploy path and the reverse SSH doorway to Jellyfin at home instead of a dead fleet of game servers.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The retired Minecraft files are no longer public.&lt;/b&gt; The deploy path now removes both old modpack downloads and the obsolete game-server JavaScript from the live server instead of leaving remote-only files behind forever.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The server got audited and then actually hardened.&lt;/b&gt; SSH is key-only with root login disabled; Hilray&#x27;s key is tunnel-only; a persistent default-deny host firewall replaced the open input surface; LLMNR is gone; Debian and its kernel are current; the retired game routes and Docker socket are gone; Caddy and the API run read-only with dropped capabilities; secrets and visitor salts were rotated; logs are capped; spoofed Cloudflare identity headers are overwritten; and direct access to the main origin is refused.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>The site became a universe, and the universe got a signal tuner</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-08-04:changelog/v2026.08.04a</id>
    <updated>2026-08-04T01:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The Harperverse is a real star chart built from the site&#x27;s own page index.&lt;/b&gt; Personal writing, projects, mental-health resources, interests, writing and community pages form separate constellations. Search and constellation filters update both the chart and its keyboard-friendly destination list.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Visited public pages glow locally.&lt;/b&gt; The map reads the same browser-only journey data the site already keeps. Adult pages remain a collapsed, clearly marked region until the visitor has already passed the existing consent flow, and their individual page names are never written into persistent visit history.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;“Throw me into the void” prefers somewhere unexplored.&lt;/b&gt; It uses the real index, respects the current search or constellation filter, excludes private and adult destinations, and falls back gracefully once every matching public star has been seen.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The global signal tuner reaches every page.&lt;/b&gt; Soft femme, dark masc, identity rift, feral web and quiet signal each alter the site&#x27;s shared palette and atmosphere. The selection stays in this browser, composes with the manual hue control, and also reaches the standalone Myspace recreation.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Quiet signal is a state, not a grey colour preset.&lt;/b&gt; It removes the starfield, static, rifts, decorative animation and smooth scrolling, stops the ambient lofi, and pauses the floating music player without deleting its queue.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Myspace came back, Tom is still first, and the Projects page finally shows its receipts</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-30:changelog/v2026.07.30a</id>
    <updated>2026-07-30T01:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;A complete Myspace recreation lives under About now.&lt;/b&gt; It started as a faithful blue-and-white profile, then got the customization it was missing: neon tiled wallpaper, Comic Sans, clashing borders, scrolling status text, profile stickers, blurbs, fake comments and exactly eight important things. Tom has the first spot, because some rules survived the old internet for a reason. &lt;a href=&quot;myspace.html&quot;&gt;Open the profile&lt;/a&gt;.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;It is linked everywhere it should be.&lt;/b&gt; The About dropdown has a Myspace Recreation entry, the About page has its own callout, site search knows the page exists, and the discovery files include it. Clicking the Myspace logo originally reloaded the recreation forever; it now returns to the real lilharper.dev homepage.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The profile song is “This Calling” by All That Remains.&lt;/b&gt; The first custom control layer looked right and did not reliably play anything, so it was replaced with the native embedded player. Autoplay is still requested, clicking Play always works when a browser blocks it, and the familiar volume and mute controls stay visible.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The player took three attempts to get honest.&lt;/b&gt; The first version was quiet and depended on a custom unmute button. The second added a volume slider and mute toggle but still depended on the same unreliable control layer. The final version uses the official player&#x27;s own controls and includes a direct YouTube link when somebody blocks embeds entirely.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The stretched Top 8 photos were a real CSS bug.&lt;/b&gt; Their HTML dimensions were still deciding the height after the grid decided the width, turning every picture into a tall sliver. The tiles now force a square aspect ratio and crop inside it instead of distorting the image.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The profile got the customization the first draft was missing.&lt;/b&gt; The plain recreation became the kind of page a sixteen-year-old would have guarded like a bedroom wall: moving rainbow chrome, impossible wallpaper, stickers, blink text, mismatched borders, fake moods, an online badge, “rawr xD,” and several color choices that should not be allowed near each other.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Myspace is a project, not an About-page easter egg.&lt;/b&gt; It now has its own card, technical notes and a current screenshot on the &lt;a href=&quot;projects.html#myspace-project&quot;&gt;Projects page&lt;/a&gt;. The About menu and About page both still link to it, and the Myspace logo returns to the full site instead of reloading the profile forever.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Myspace project card has its own receipts now.&lt;/b&gt; Its screenshot is cropped around the recognizable header and profile instead of shrinking the whole tall page into a card. It also has its own source, Top 8 and link counts, plus copyable snippets for the tiled wallpaper and the square-image repair.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Projects page shows real code with the result beside it.&lt;/b&gt; Two excerpts from Hazel are paired with the Discord output they produce. Each can be copied normally or copied with Discord&#x27;s fenced-code formatting already wrapped around it.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Source statistics have a definition now.&lt;/b&gt; Hazel, Hazel Care and lilharper.dev show physical source-line and file counts, dated and scoped so the numbers say what was counted. Backups, dependencies, generated builds and retired files are excluded.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Five old publication failures were cleaned up along the way.&lt;/b&gt; Three redirect pages gained proper main landmarks, and two prose lines stopped violating the site&#x27;s punctuation rule. The publication checks are clean again, including the new authorship-language guard.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The authorship rule is enforced instead of remembered.&lt;/b&gt; The publication script now scans for wording that attributes the apps or website to automated authorship and refuses to release if it finds any. The existing mentions of local-model infrastructure and a retired feature are separate factual topics; neither is presented as the author of this work.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Music videos can follow you around the entire site now, including Myspace.&lt;/b&gt; Starting any verified showcase video opens one floating mini-player outside the part of the page normal navigation replaces. The video you choose becomes the beginning of a continuous Top Picks queue that automatically works through every other verified favourite and loops around. Previous and next buttons let visitors move around the queue without returning to Music, and the title updates to match each new video. Their first version waited for an unreliable ready signal from the privacy-enhanced YouTube embed, leaving them disabled with a loading cursor; they now switch the queue directly and work as soon as the player opens. The queue survives Myspace&#x27;s full old-school page load too, restoring the current video near the same playback position and temporarily holding the profile song so two tracks do not fight each other. The player can collapse into a little queue bar, restore, switch cleanly to another starting point or close and stop.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Every revision was released through the normal safety path.&lt;/b&gt; Each publication passed the link, asset, heading, landmark, house-style, social-card and live-status checks, backed up the previous live copy, uploaded only changed files, purged the edge cache and verified the homepage answered afterward.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>233 wrong genres, a chip that split itself in half, and a like button that never worked on five pages</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-28:changelog/v2026.07.28a</id>
    <updated>2026-07-28T01:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Genre Spotlight was wrong in more places than I first noticed.&lt;/b&gt; Twenty One Pilots and The Weeknd were both filed as Pop (they&#x27;re not), Poppy and PVRIS were filed as Alternative when they&#x27;re rock, Lil Peep was filed as Alternative instead of rap, and The Midnight was sitting in R&amp;B/Soul when they&#x27;re a synthwave duo. All five, plus Mithril Oreder, are top-150 artists so the fix lives in &lt;code&gt;music-graph.js&lt;/code&gt;, which is the one place that can&#x27;t disagree with the galaxy.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Then I asked for the rest of &quot;Other&quot; to actually get looked up&lt;/b&gt; instead of guessed. 233 artists across the full 489-artist list got checked against Wikipedia, Genius or AllMusic and reclassified where a source actually backed it up. &lt;code&gt;genreKnown&lt;/code&gt; went from 247/489 to 473/489. Sixteen stayed &quot;Other&quot; on purpose -- a couple of name collisions with no way to confirm which artist was meant, a game soundtrack, a philosopher&#x27;s spoken-word recordings, and two jazz vocalists the site&#x27;s genre buckets were never built to hold. Forcing a bucket on those would&#x27;ve been a worse answer than leaving them alone.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A tag could split itself into two chips.&lt;/b&gt; The &quot;win me over&quot; pill row on the Love page had no rule stopping a long tag&#x27;s text from wrapping mid-pill, so &quot;a song you thought I&#x27;d like&quot; broke across a line and rendered as if &quot;like&quot; were its own stray chip. &lt;code&gt;.tag&lt;/code&gt; now gets &lt;code&gt;white-space: nowrap&lt;/code&gt;, so a whole pill moves to the next line as one unit instead of tearing in half.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Fluent in Dog photo was cropping out everyone in it.&lt;/b&gt; The shared about-hero photo box is 260x420, tuned for portrait headshots; Harley2.jpg is a wide 1200x900 shot with Harley at the far left edge and me crouching at the far right, so a centered crop straight down the middle cut out both of us and kept the empty grass in between. That page now gets its own wider box that actually matches the photo&#x27;s shape. Also corrected: I&#x27;ve never worked as a dog trainer, only a paid dog walker, and the whole behaviorist side of this is a hobby and a passion, not a credential.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reactions have been silently broken on five pages since they launched.&lt;/b&gt; The server checks every page id against a fixed allow-list before it&#x27;ll count a reaction, and dogbehaviorist, fhrt, receipts, servers and shitpost were never added to it. Their like/love/OMFG WHAT buttons have been pressing into a 404 this whole time with no visible error. Added to the list; needs a VPS deploy of &lt;code&gt;reactions_api.py&lt;/code&gt; to actually take effect.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The genre galaxy&#x27;s connection lines are fractures now, not wires.&lt;/b&gt; Straight &lt;code&gt;&amp;lt;line&amp;gt;&lt;/code&gt; edges became jagged multi-segment paths, seeded off each edge&#x27;s own artist names and index so the crack pattern is identical on every load rather than reshuffling -- same rule as the rest of the galaxy&#x27;s deterministic layout. Every line still runs from the same star to the same star and is still clickable through to its source; only the shape of the trip between them changed.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reddit stays, minus the parts that point back to my actual account.&lt;/b&gt; I went back and forth on this one and landed on: the information can stay public (the dated 2017 headphone post, the 2018 A Perfect Circle ranking, the subreddit list on About), but the two direct reddit.com permalinks in the music page&#x27;s receipts no longer render as clickable links, since following either one shows the poster&#x27;s account on the post itself. The words are still quoted in full, verbatim, just not one click away from the account they came from.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>I measured how I actually write, found the site was not doing it, and then broke it twice fixing that</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-27:changelog/v2026.07.27d</id>
    <updated>2026-07-27T04:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Click a photo and it opens at full size.&lt;/b&gt; Every content image on the site is now expandable, with the real pixel dimensions printed under it, arrow keys to move through the photos on a page, Escape to close, and focus returned to exactly where it was. It skips images inside links, decorative ones, and anything under 200px, because offering to enlarge a 165px picture to 165px is a promise you cannot keep.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The rifts shoot lightning now.&lt;/b&gt; The corruption arcs that were designed days ago finally exist: bolts fire out of a random rift every few seconds and briefly tear up whatever they land on. The CSS had been sitting there doing nothing the whole time because the script that drives it was never written, which I had reported as finished. It was not. It is now.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;I measured my own voice instead of guessing at it.&lt;/b&gt; I ran my Facebook posts, my Instagram captions and my approved blog drafts through the same script as the site&#x27;s prose and compared them on the same metrics. The result was blunt: I use contractions at roughly twice the rate the site did, first person two to three times as often, and I have never once written the phrase &quot;rather than&quot; in 27,904 words of my own writing. The site had used it 569 times. That is not my register leaking, it is somebody else&#x27;s.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;So 29 pages and 30 gated fragments got rewritten.&lt;/b&gt; &quot;Rather than&quot; is now at zero everywhere except this changelog, which is a build log and gets to keep its own voice. Contractions went from 196 per ten thousand words to 314. Filler like &quot;actually&quot; and &quot;genuinely&quot; dropped by nearly half, to inside the range my own writing sits in. Nothing on any page changed what it claims; every number, date, name and link came out the far end untouched, which I checked by fingerprinting each file before and after and comparing the tag structure and every digit.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The gated pages hold more writing than the rest of the site combined.&lt;/b&gt; 79,799 words across 30 fragments, against 66,011 in all 70 ordinary pages. They had never been through any of it, which I only discovered because I went looking for something else.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;Two bugs of mine, same bug, twice.&lt;/b&gt; The contraction pass shipped 26 broken sentences to the live site: &lt;code&gt;Some of it&#x27;s who I&#x27;m&lt;/code&gt;, &lt;code&gt;whoever you&#x27;re, you deserve&lt;/code&gt;, &lt;code&gt;the oldest kind of self-hosting there&#x27;s&lt;/code&gt;. A contraction of is/are/am cannot sit at the end of a clause, and a rule that is right in the middle of a sentence is wrong at the end of one. I fixed those, added a deploy check so it could not happen again, then ran the same pass over the gated fragments and did it 30 more times. The check had not been looking at that folder. It is now, and both halves come back clean.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The Twitch tab is a button and a menu.&lt;/b&gt; Clicking the label goes to the stream page, the little arrow beside it opens the dropdown. It had been broken since I made the label a link while it still carried the dropdown&#x27;s click handler: the menu opened and the browser navigated away about forty milliseconds later, so what you saw was a dropdown that did nothing.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The comfort pages stopped being a thunderstorm.&lt;/b&gt; The caregiver, pet regression, ABDL, ageplay and Harley pages had a warm lamp-lit theme underneath six rift cracks, a magenta nebula and a pixel grid, and the paragraph explaining that Mama&#x27;s real name is deliberately kept off the page was hard to read through all of it. Those pages now turn the noise down: no rifts, no static, starfield at a quarter, and a warm wash in its place. The stickers stay, because a sticker is cute and a rift is corruption, and only one of those belongs on a page about feeling safe.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The 24/7 page doubled, and the new half is about coercive control.&lt;/b&gt; A healthy dynamic and an abusive relationship use identical vocabulary, so the words cannot tell them apart. Six things can: where the authority came from, what leaving costs, whether it ever gets reviewed, who else is allowed to know, who benefits, and what happens when you say no. Plus how people actually start one, the unglamorous infrastructure that keeps it safe, how it ends, and how it interacts with being neurodivergent.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The ranked artist list went from 250 to 489.&lt;/b&gt; That covers 4,632 songs, 88% of the library instead of two thirds. It costs something and the page says so: I have a genre on file for 247 of the 489, so about half the new arrivals sit in &quot;Other&quot; until I classify them. The counts are all real. The colour is the part that is not finished.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;The shitpost wall is gone.&lt;/b&gt; Its 50 images were hotlinked to Facebook&#x27;s CDN, which signs every link with an expiry roughly four days out, so the whole page was on course to become fifty broken boxes on 31 July with nothing in any log to say why. Instead of re-hosting them I removed the section. The changelog entries about building it stay, because this file is a record of what happened and editing that would break the only rule this site really has.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;29 images were still carrying camera metadata,&lt;/b&gt; including timestamps and a phone model, on a site that is otherwise pseudonymous. Stripped losslessly, pixels untouched, verified by re-reading every JPEG afterwards.&lt;/li&gt;

            &lt;li&gt;&lt;b&gt;Also:&lt;/b&gt; the deploy script was refusing to run at all, reporting 26 em-dashes that did not exist, because PowerShell was reading UTF-8 files as Windows-1252 and the third byte of a trash-can emoji happens to be an em-dash in that encoding. The flame effect got harsher, with roughly double the throw and a chromatic tear that now shifts hue between frames. The blueprint installer accepts a 405 as proof a POST-only route loaded. Pipes between the loud nav buttons. A glow on Twitch that breathes faster when I am actually live, and one on Help in red, orange and white.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Hazel plays my music into Discord now, and it took eleven bugs to get there</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-27:changelog/v2026.07.27c</id>
    <updated>2026-07-27T03:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Hazel can play my music in a voice channel.&lt;/b&gt; Not by downloading anything: she relays what&#x27;s already coming out of my speakers. My desktop audio goes into VoiceMeeter, which splits it to my headphones and to a virtual recording device, FFmpeg opens that device like a microphone, and the live audio goes straight into her voice connection. Nothing is fetched or stored, which is the entire reason this approach doesn&#x27;t run into the problem that killed Rythm and Groovy. &lt;a href=&quot;projects.html#hazel&quot;&gt;The full explanation is on the Hazel project page&lt;/a&gt;.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A now-playing panel with working transport controls.&lt;/b&gt; The YouTube Music desktop app exposes a small local server, so the Command Centre pairs with it once and can then show the current track and drive play, pause and skip. It&#x27;s a remote rather than a second player, so pressing skip in the app, on my keyboard, or in Hazel all do the same thing to the same player.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Eleven distinct bugs, and I want them written down.&lt;/b&gt; A constant that got deleted by an edit landing on top of it, so the launcher died on startup. A console window flashing every five seconds because a background call spawned a process without hiding it. An FFmpeg output parser written for a format that changed five years ago, which reported zero audio devices on a machine with plenty. A version string with two numbers where the API demanded three. A URL with a prefix on it that the docs specifically say must not be there. A dialog nobody was told to go and look at. And a device name that differed only in one capital letter.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The one that&#x27;s worth remembering.&lt;/b&gt; None of those eleven were syntax errors. Every single one parsed perfectly and failed only when it ran, which is exactly the class of thing that &quot;the code is valid&quot; can&#x27;t catch. Somewhere in the middle of this I stopped trusting that and started scanning for names that get read but never defined, and that immediately caught the next one before it shipped.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Two things that sounded like my setup and were actually the code.&lt;/b&gt; Music through Discord sounded like a phone call, because voice channels default to a speech-optimised encoder and nobody had told it otherwise. And it stuttered because a live audio capture will silently throw audio away rather than wait when something downstream stalls. Both fixed; neither had anything to do with my microphone, my headphones, or my network.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>My own stream page, nine months of my own bios, and two bugs of mine that had been quietly lying to people</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-27:changelog/v2026.07.27b</id>
    <updated>2026-07-27T02:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;New page: my live stream.&lt;/b&gt; A &lt;a href=&quot;twitch.html&quot;&gt;page that becomes the stream&lt;/a&gt; when I&#x27;m live, player and chat together, and a real offline card when I&#x27;m not. It never says &quot;offline&quot; when what actually happened is that it couldn&#x27;t reach the status API, because those are two different claims and only one of them would be true. There&#x27;s a Live button in the top bar, and a red dot appears on it from anywhere on the site the moment I actually go live.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Nine months of rewriting my own bio.&lt;/b&gt; I exported my Instagram data out of curiosity and found it timestamps every profile edit, which means I had accidentally kept a diary. &lt;a href=&quot;trans.html#bios&quot;&gt;It&#x27;s on the trans page now&lt;/a&gt;, in order, quoted exactly: &quot;Gender under construction&quot; in November, &quot;☆ trans girl ♡&quot; in March, and in May the name shortening to just Harper. That page used to say I&#x27;d never publish a timeline. I changed my mind halfway and rewrote the paragraph to say where the line now sits: no medical dates and no legal dates, ever. Bios I already posted in public are a different thing.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;What the archive remembers.&lt;/b&gt; The &lt;a href=&quot;about.html#archive&quot;&gt;about page&lt;/a&gt; now quotes my old Facebook bio back at me, including &quot;I like talking, I like thinking, let me know if you want a conversation,&quot; which I apparently wrote as a mission statement for a Twitch channel about a decade early. Plus the thousand-word headphone review I posted in 2017, and playlists I&#x27;ve been quietly maintaining since then.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A real listening log, finally.&lt;/b&gt; The &lt;a href=&quot;music.html&quot;&gt;music page&lt;/a&gt; has always said it can&#x27;t build a timeline because the library export has no dates in it. Spotify has since handed over a small streaming history that does. It&#x27;s three weeks long and most entries are skips of a few seconds, so the page marks which is which per row rather than dressing seventeen plays up as &quot;recently played.&quot;&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Two of my own bugs, both of which were quietly lying.&lt;/b&gt; The floating reaction buttons were written to render the inline strip &lt;i&gt;or&lt;/i&gt; the corner bubble, never both. That meant on the eleven pages carrying the inline strip (about, music, home, trans, harley and others) you scrolled past the top and had nothing left to press. Both render now, sharing one state, so pressing either updates both. Separately, the imgur file-extension check tried &quot;gif&quot; before &quot;gifv&quot;, so every imgur video on the wall had been silently rendering as a frozen still.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The wall sorts by type.&lt;/b&gt; Images and Videos filters on the meme dump, driven by the actual file extension rather than a label stored when the link was first posted, which is exactly what broke my first attempt at it. Embeds wait for a click, the newest ten sit large at the top, and nothing autoplays.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The hit counter is padded, and says so.&lt;/b&gt; The &lt;a href=&quot;guestbook.html&quot;&gt;guestbook&lt;/a&gt; counter now starts at 23,000, exactly like every counter on every homepage in 1998, because I asked for it to be. The digits still move when you reload, because the real per-browser count underneath is still real. The note under it explains all of that.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Also:&lt;/b&gt; 80 newly researched connections in the genre galaxy, every one sourced, taking it to 215 across 133 artists, with the seventeen artists I could find nothing verifiable for still named as such. Cleaning guides on the cannabis page. A nicotine harm-reduction section that attributes the &quot;95% safer&quot; figure rather than repeating it. Enshrouded on the infrastructure diagram and in the sidebar.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>102 favourite games sorted into categories, a streamers page, and a near-miss with the deploy script worth writing down</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-27:changelog/v2026.07.27</id>
    <updated>2026-07-27T00:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;My favourite games, properly sorted.&lt;/b&gt; 102 of them across eleven categories on the &lt;a href=&quot;gaming.html&quot;&gt;gaming page&lt;/a&gt;: MMOs, RPGs, Final Fantasy on its own because otherwise it buried everything, ARPGs, roguelikes, survival and building, shooters, strategy, co-op, the ones I own but need a group for, and what I&#x27;m actually hyped about.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Fourteen of those entries quote me from the time,&lt;/b&gt; pulled out of my own Facebook export rather than written for the page. The Guild Wars 2 one is twenty years of my life in a paragraph I don&#x27;t remember writing. Only public posts and comments were searched, never messages, because my half of a DM is still half of somebody else&#x27;s conversation.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;New page: the streamers I actually watch.&lt;/b&gt; Seventeen Twitch channels with a player for each. The players only load when you press the button, because seventeen embeds firing at once would make the page miserable on a phone. It also doesn&#x27;t claim to know who&#x27;s live: checking that properly needs a Twitch API token a static site can&#x27;t hold, so the page says so instead of faking a badge.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A near-miss worth recording.&lt;/b&gt; Fixing a missing comma in the deploy script&#x27;s file list, I ran a find-and-replace across the whole file instead of just that array, and it inserted commas into the robocopy exclusion list, which is space-separated. That list is what keeps .env, .pem, .key and .bak files off the public site. It would have silently stopped excluding them. Caught it, restored the block, audited every other line in the file, and this entry exists so the shortcut looks as bad next time as it turned out to be.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>I counted every word I&#x27;ve written online since 2011, and the glow now travels around the button instead of spinning behind it</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26q</id>
    <updated>2026-07-26T17:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;813,025 words.&lt;/b&gt; I pulled my full Facebook and Instagram exports and counted everything I have personally typed on either platform since November 2011: posts, comments, captions, and messages I sent. That&#x27;s about ten novels, or sixteen NaNoWriMos. The &lt;a href=&quot;writing.html&quot;&gt;writing page&lt;/a&gt; has the breakdown.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;My first count was wrong and it&#x27;s worth saying why.&lt;/b&gt; I started from a derived spreadsheet and got 513,000, which felt low. It was: that dataset had deliberately stored messages as metadata only, so the single largest body of my writing wasn&#x27;t in it, and the Instagram export is HTML with no JSON at all so none of it had been counted either. Going back to the raw exports found another 300,000 words. The lesson is that a tidy intermediate file isn&#x27;t the same thing as the source.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;What the numbers say about me, unflatteringly:&lt;/b&gt; my most-used content word is &quot;people&quot; (3,034 times), my median piece of writing is ten words long, my peak writing hour is 11pm, and I have typed &quot;dog&quot; 1,378 times against &quot;love&quot; 997 times. Harley wins by nearly four hundred.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Deliberately not counted, and not stored anywhere:&lt;/b&gt; who I was talking to, what anyone said back, and any per-person breakdown. Those conversations belong to the other people in them too, and none of them agreed to be a statistic on my website.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;There&#x27;s a photo of me and Wolfie in the little section now,&lt;/b&gt; framed like a polaroid taped to the page. It&#x27;s displayed small on purpose: the file came through a chat upload that had already squashed it to 165 pixels wide, so blowing it up would just make it blurry. A snapshot is the right register for that section anyway.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The gaming page now has the actual arc,&lt;/b&gt; in phases: pure wonder as a kid, competitive shooters as a teenager, StarCraft and League as a young adult, and RPGs running underneath all of it the whole time. Plus what I&#x27;m obsessed with right now (Enshrouded, Tabletop Simulator for Gloomhaven and Magic, Palworld, Some of You May Die, Gamble With Your Friends) and the RPGs I keep going back to. The honest current filter is that I mostly play whatever lets me talk to people at the same time.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The glow on Blog, Shitposts and Harm Reduction travels around the border now&lt;/b&gt; rather than rotating behind the button. Getting there took two tries: rotating the element itself sweeps its own diagonal, and since these are wide pills that threw bright streaks above and below the nav bar. Animating the gradient&#x27;s angle instead, and masking everything except the two-pixel ring, keeps the light on the border where it belongs.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>The nav got reorganised again, harm reduction became its own help button, and the blog can be pinned and replied to without clicking through</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26p</id>
    <updated>2026-07-26T16:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The glowing buttons were too much, so they&#x27;re lighter now.&lt;/b&gt; Lavender instead of saturated purple/pink, the shine pooling under the button and around its border instead of blazing off it, and every animation slowed from about two seconds to four and a half. The floating search button got the same treatment for the same reason: it&#x27;s on screen on every page, all the time, and it was pulsing like something was wrong.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Identity &amp;amp; Health and Neurodivergent both folded into About Me.&lt;/b&gt; The distinction that survives isn&#x27;t topic, it&#x27;s question: About Me answers &quot;who is she&quot; (trans, AuDHD, ADHD, dissociation, therapy, love, Harley, character sheet), Interests answers &quot;what is she into.&quot;&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Harm reduction is its own button now, in amber rather than lavender,&lt;/b&gt; because it isn&#x27;t another page I&#x27;m proud of, it&#x27;s the one someone might land on at 3am needing actual information. It should look like a first-aid sign, not a feature. There&#x27;s exactly one button in that colour and there should stay exactly one.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The site changelog moved under Projects&lt;/b&gt; (reading it&#x27;s closer to browsing what got built than to reading an essay), and Writing now holds essays plus the blog. Blog is deliberately the one duplicated entry in the nav: in the Writing menu because that&#x27;s where you look for my writing, and still its own button because it&#x27;s the page that changes most and burying it one hover deep is how a blog quietly goes dead.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The featured post on the blog is the pinned one now, if there&#x27;s one,&lt;/b&gt; rather than always the newest. Pinning is how I say &quot;start here,&quot; and before this it only reordered the list while the loudest card stayed whatever I wrote last.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Comments show on the featured post directly,&lt;/b&gt; so the post most people read is also the one they can reply to without a click-through. Other cards still link out; loading every thread on page load would be one network request per post.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;I can pin and unpin from the blog page itself&lt;/b&gt; instead of opening the post in the editor. It flips one flag through a new endpoint rather than re-uploading the whole post, and pinning is exclusive, so pinning one thing unpins the last one in the same write.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;There&#x27;s a proper section about being little on the About page now,&lt;/b&gt; and it has its own soft pink styling: rounded, stars and hearts drifting along the top, a row of favourite things (Bluey and Muffin, Hilda, goldfish, Wolfie, soft clothes). Every other part of this site is CRT purple and sharp corners, which is the wrong frame for that paragraph. It reads as a different room in the same house. The decorative bits are all hidden from screen readers, so nothing there carries meaning the words don&#x27;t already say.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Blog and Shitposts are glowing buttons now, an ABDL page, and everything fades in as you scroll to it</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26o</id>
    <updated>2026-07-26T15:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Blog and Shitposts sit on their own at the end of the top bar, both wearing the site&#x27;s glow&lt;/b&gt; instead of the old flat lime tint: the same purple/blue/pink recipe as the sidebar photo, shaped to a pill, with a blurred conic-gradient ring rotating behind each one. The bar used to allow exactly one loud item, on the theory that a second one cancels the first. That held while the highlight was a colour that fought the bar; two matched glowing buttons read as a pair instead. Two is still the ceiling.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The glow had to be tuned down from what looked best in isolation.&lt;/b&gt; The top nav is a horizontal scroll container, so anything drawn outside a link gets clipped flat at the bar&#x27;s edge, and the sideways spill hazed over the &quot;Connect&quot; link next door. Checked in a real browser, tightened, and checked again.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;New page: ABDL,&lt;/b&gt; in the Adult Dynamics menu behind the same age gate as the rest of that section. AB and DL are written as two separate things that happen to share a shelf rather than one blurry acronym, with a section on where the circles actually overlap: age regressors who wear specifically because of how well it triggers the headspace, people for whom there&#x27;s no sexual element at all, people for whom it&#x27;s purely a kink, and every mix in between.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Content fades in as you scroll to it now, everywhere on the site.&lt;/b&gt; Cards, callouts, section headings, and glossary rows arrive as you reach them instead of having already animated before you got there. Grid rows stagger against each other. If the script fails to load, or you have reduced motion turned on, nothing is hidden and nothing moves, because the hiding is applied by the script itself rather than sitting in the stylesheet waiting to be undone.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Cards lift slightly on hover&lt;/b&gt; now, the interactive ones only. Prose blocks deliberately don&#x27;t move when the cursor crosses them.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>A shitpost feed for memes, the CG/L page got a couple more real details, and the sidebar photo/search button both got the glow treatment</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26n</id>
    <updated>2026-07-26T14:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;New page: the shitpost feed.&lt;/b&gt; Paste a link (a YouTube video, a tweet, a TikTok, a Reddit post, an image, a clip, or basically anything else) and it embeds right there, pulled live from wherever it actually lives -- nothing gets uploaded or copied through this site, so the traffic and the credit both stay with the original host. It&#x27;s saved in this browser only for now, which is an honest limitation rather than a hidden one: a different device starts with an empty feed until this gets a real shared backend later.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Caregiver / Little page picked up two small, specific details&lt;/b&gt; instead of staying purely conceptual: what the actual comfort item is (a wolf plushie named Wolfie, promoted from stuffed animal to permanent coworker somewhere around year two) and a couple of the small, unglamorous rituals that turned out to matter more than the big ones.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The character sheet portrait and the floating search button now pulse with the same purple/cyan/green glow&lt;/b&gt; as the sidebar photo, instead of being the only two circular elements on the site that didn&#x27;t.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The About Me dropdown was one long list of identity pages and hobbies mixed together; it&#x27;s three now.&lt;/b&gt; About Me kept the core identity pages (about, character sheet, now, love, Harley). Food, Gaming, Music, Cannabis, and the new shitpost feed moved into a new Interests group. AuDHD and ADHD &amp;amp; Hazel Care moved out of Identity &amp;amp; Health into their own Neurodivergent group next to About Me, since browsing one of those pages usually means wanting the other, not the trans-health or harm-reduction pages they used to sit beside.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Love &amp;amp; Attraction page names two more labels that were true the whole time&lt;/b&gt; but hadn&#x27;t been spelled out: demisexual and sapiosexual, alongside the grey asexual label already there. In plain terms, a spark usually needs an actual bond to exist first and tends to get triggered by someone&#x27;s intelligence and curiosity once it shows up, which is also why it&#x27;s slow to arrive; the page now says outright that I deliberately keep sitting with someone even when nothing sparks right away, because for me that&#x27;s often just what the process looks like before a connection has room to form.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>A searchable genre galaxy, post-video song suggestions, real infra nodes, a reworked Lights panel, and one lofi track instead of four</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26m</id>
    <updated>2026-07-26T13:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Google Home, the cameras, and the Govee lights are now real nodes&lt;/b&gt; on the infrastructure page&#x27;s network diagram, not just prose further down the page. The camera node is labeled &quot;Cameras,&quot; matching the existing writeup, since that section deliberately never names the brand.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Fixed a startup crash in the Hazel Command Centre&lt;/b&gt; (&quot;bad screen distance&quot;) introduced while moving the Lights and Hazel AI panels back into the main window: a couple of Frame widgets were built with a two-part padding value that only Tkinter&#x27;s pack/grid calls accept, not a widget&#x27;s own constructor.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The Lights panel moved below Operations, full width, in a two-column grid of light cards&lt;/b&gt; instead of a narrow column squeezed beside it, and Operations&#x27; own DEPLOY / API SERVICES / SERVER / GAME SERVER &amp; FLAVI groups can each collapse now, so the ones not in use can get out of the way.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Brightness is a small vertical slider now&lt;/b&gt; instead of a full-width horizontal one, it can target just the lights that are checked instead of always every light in the room, and its per-device Govee calls are staggered instead of firing all at once -- a likely fix for lights not responding to a group brightness change, based on the same kind of multi-light timing behaviour the Govee app itself has.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Renaming a light is just clicking its name&lt;/b&gt; now, no separate button, and lights can be reordered with per-card up/down arrows -- the order is saved and persists across restarts.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The ambient lofi player is one combined track now, not four switchable moods.&lt;/b&gt; Late night and Deep focus are stitched into a single longer piece; the mood picker is gone from the sidebar, leaving just play/pause and the volume slider.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A second research pass on the music page&#x27;s genre galaxy added 15 more sourced connections&lt;/b&gt; (117 total now, up from 102, between 65 artists), each with a concrete basis and a source link like the rest of the dataset. The whole layout was re-simulated afterward so the newly-connected artists actually landed near each other instead of the map only being accurate for the older edges.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The genre galaxy is searchable now.&lt;/b&gt; Typing an artist&#x27;s name shows a dropdown of matches; picking one highlights their star with the same pulsing purple/cyan/green glow as the sidebar photo (adapted for the galaxy&#x27;s SVG stars) and opens their connections panel. Artists with no documented connection now get an honest fallback list of other artists in the same genre instead of a dead end, and every artist&#x27;s panel now includes a few of their real top songs from the library export. Both areas link to each other, so browsing from one similar artist to the next doesn&#x27;t require closing the panel and re-searching.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Pressing play on a showcase video now suggests what to watch next,&lt;/b&gt; right below the card, in the same video-plus-lyrics format as the rest of the showcase. Suggestions prefer a real, sourced connection from the galaxy&#x27;s research (labeled with what the connection actually is: toured together, collaborated, same label) before falling back to same-genre picks, and each suggestion can be played too, cascading into more without ever repeating an artist already on screen.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A third research pass added 18 more sourced connections&lt;/b&gt; (135 total now, up from 117, between 87 artists) -- Kanye West, Kid Cudi, Common, Nas, Eminem, Wale, and a handful of others who previously had no documented connection now do. Only the newly-connected artists were re-simulated this time (not the whole map), so everyone else&#x27;s star sits exactly where it did before.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Blog comments, a suggestion box, and the front door actually leads with About Me now</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26l</id>
    <updated>2026-07-26T12:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Blog posts can be commented on.&lt;/b&gt; Every published post now has a comment thread underneath it: name required (unlike the guestbook&#x27;s optional name), message required, honeypot-protected and rate-limited server-side, moderated the same way the guestbook already is. Reuses the existing boxed-form styling from the Work With Me page rather than inventing new CSS for it.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A suggestion box now lives on the Contact page,&lt;/b&gt; embedded right in the page instead of only being reachable through the floating &quot;Ask me anything&quot; bubble. It&#x27;s the same inbox underneath, no new backend and no second moderation queue, just a second, more discoverable way in.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Fixed a real bug in the &quot;latest post&quot; card on the blog:&lt;/b&gt; it was picking whichever post happened to load last from the API and assuming that meant newest, which quietly broke the moment that assumption stopped holding, and the enlarged card could end up being an older post while a newer one sat in the small-card list beneath it. It now finds the actual newest post by comparing dates directly.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;That featured post now shows in full on the page,&lt;/b&gt; body text and all, instead of a short excerpt behind a &quot;Read the rest&quot; link, so the latest post can be read start to finish without a click-through.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;About Me is the actual front door again.&lt;/b&gt; A first-time visit still gets the entrance splash, but the &quot;Enter the site&quot; button had drifted to pointing at the tech dashboard instead of About Me, so every new visitor was landing on the dashboard regardless. Fixed to match how it was meant to work: first impression is About Me, &quot;Home&quot; in the nav still means the dashboard for everyone after that.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Walked back some of the fire theme: the sidebar&#x27;s calmer, the glow&#x27;s not on fire anymore</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26k</id>
    <updated>2026-07-26T11:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The sidebar&#x27;s green paint-splatter and the &quot;RAWR XD&quot; graffiti tag are gone,&lt;/b&gt; along with the small character-stat card (level/alignment, INT/CHA/DEX boxes, mood meters) that sat below the avatar. The separate &quot;Your journey&quot; progress widget stays untouched; it&#x27;s a different piece.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;The avatar&#x27;s glowing ring is purple/cyan/green now instead of fire-toned&lt;/b&gt; (it was yellow/orange/red before). Same spinning halo, same animation, just recolored to match the rest of the site&#x27;s palette instead of standing out as the one warm-toned thing on it.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;That same glow now shows up in two more places, more subtly:&lt;/b&gt; a quick purple/cyan/green pulse under a button the moment you click it, and a faint ambient glow drifting behind the heading on every gated content page. Both respect reduced-motion the same way everything else on the site does.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>The background isn&#x27;t empty anymore, there&#x27;s static living behind everything</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26j</id>
    <updated>2026-07-26T10:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;A faint, always-on noise/static layer now sits behind every page,&lt;/b&gt; a soft scanline-and-grain texture that slowly drifts through hue and breathes in opacity. This is separate from &lt;code style=&quot;color:var(--purple-bright);&quot;&gt;glitch.js&lt;/code&gt;&#x27;s scroll/idle bursts, which are still occasional and loud; this new layer is the quiet, persistent version, closer to the &quot;always a little noisy back there&quot; look in the reference Steam-profile mockup.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Built additive, not a replacement.&lt;/b&gt; It sits directly on top of the existing starfield in the stacking order, both stay fixed behind every panel, and panels are already 75% opaque, so nothing about readability changes.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reduced motion keeps a faint static texture but freezes the hue drift and breathing,&lt;/b&gt; same &quot;freeze in place, don&#x27;t fully vanish&quot; treatment as the avatar ring&#x27;s flame flicker.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>The glitch effect covers the whole site now, and Ask Me Anything got wired into the launcher</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26i</id>
    <updated>2026-07-26T09:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Signal corruption (&lt;code style=&quot;color:var(--purple-bright);&quot;&gt;glitch.js&lt;/code&gt;) got turned up instead of duplicated,&lt;/b&gt; same principle as always: it already touches every page equally (it hue-shifts whatever&#x27;s underneath, text or image or canvas, with no idea what it&#x27;s corrupting), so &quot;apply the reference glitch-art&#x27;s aesthetic to the whole website&quot; meant amplifying this one mechanism, not building a second one. Fires roughly 2.5x more often, bands are bigger, and the colour range widened from a green/cyan-only rotation to also roll through magenta and amber, closer to the purple / green / fire variants in the reference images. Pages that see little or no scrolling now also get an occasional idle-triggered burst, so corruption isn&#x27;t purely scroll-gated anymore.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;&quot;Ask me anything&quot; is now one of the launcher&#x27;s API installers,&lt;/b&gt; alongside Blog, Reactions and Guestbook. It quietly wasn&#x27;t on that list before, which meant updating it needed doing by hand over SSH even though the button for exactly this already existed.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reduced motion, the off switch, and the existing cooldown all still apply&lt;/b&gt; to the amplified glitch effect and its new idle trigger, unchanged.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Pulled real reference in: the avatar has a flame border now, and the sidebar got a little terminal</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26h</id>
    <updated>2026-07-26T08:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The sidebar avatar ring now has a flickering flame-colored halo&lt;/b&gt; layered around the existing spinning purple/amber ring, echoing the actual fire border on Harper&#x27;s own Discord avatar decoration rather than a generic glow.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;&quot;RAWR XD&quot; got a real graffiti treatment.&lt;/b&gt; The sidebar&#x27;s fixed tag (not the random rotating page-head ones) is now bold outlined spray-paint-style text instead of a filled pill, closer to the actual &quot;RAWR!&quot; profile effect it&#x27;s referencing.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A small fake terminal now lives in the sidebar,&lt;/b&gt; a couple of &quot;root@lilharper:~#&quot; lines with a blinking cursor, purely decorative flavor text (aria-hidden), pulling in the terminal/CRT feel from the reference mockups without touching the sidebar&#x27;s actual structure.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Also added a &quot;Discord username or email&quot; field to the &quot;Ask me anything&quot; widget,&lt;/b&gt; optional, so a message in Harper&#x27;s DMs actually comes with a way to reply. Mirrors the same &quot;Contact&quot; field pattern the Work/Collaborate form already uses.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reduced motion turns the new flame flicker and terminal cursor off cleanly,&lt;/b&gt; same guarantee as everything else.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>Turned it up again: the bratty pass wasn&#x27;t actually loud yet</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26g</id>
    <updated>2026-07-26T07:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;The last entry undersold itself.&lt;/b&gt; Everything it described was real and live, but sized and placed subtly enough that it read as barely-there instead of &quot;RAWR XD.&quot; Same mechanisms, no new ones, just every dial pushed up: the two corner rifts nearly doubled in size and brightness and a third one joined them (top-right, bottom-left, and now a third along the left edge), the sidebar splat grew from a small blob into something that actually reads as a paint hit, and every sticker (sidebar and page-head) got noticeably bigger with a stronger glow.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Page-heads now guarantee a fire sticker&lt;/b&gt; alongside the random emoji + tag pair, so no page can luck into a quiet combination anymore. Both pools also grew: three more emoji (rage mark, rainbow, little devil) and four more chaotic tag lines.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Nav ticks pulse on their own now,&lt;/b&gt; not just on hover, and got a third bigger.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Mobile keeps the rifts instead of hiding them,&lt;/b&gt; just shrunk and repositioned so nothing overlaps content; the extra sidebar sparkle and third page-head sticker stay desktop-only so a small screen doesn&#x27;t get crowded.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Reduced motion still turns all of it off cleanly,&lt;/b&gt; same guarantee as every pass before this one.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
  <entry>
    <title>The bratty pass, turned up: rifts, splatters, and stickers that actually shout</title>
    <link href="https://lilharper.dev/changelog.html"/>
    <id>tag:lilharper.dev,2026-07-26:changelog/v2026.07.26f</id>
    <updated>2026-07-26T06:00:00Z</updated>
    <content type="html">&lt;ul&gt;
            &lt;li&gt;&lt;b&gt;Round one of the bratty redesign read as tasteful, not bratty.&lt;/b&gt; This is the louder follow-up: two glowing &quot;tear in reality&quot; shapes now sit fixed in the corners of every page, hand-built jagged outlines filled with the site&#x27;s own purple/pink/cyan gradient, slowly breathing brighter and dimmer rather than sitting static. They&#x27;re decoration behind the content, not on top of it, so they never compete with anything you&#x27;re trying to read.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;A green paint splatter and a couple of jittering stickers now live around the sidebar photo&lt;/b&gt; (&quot;RAWR XD&quot; is currently living rent-free there), and every gated page&#x27;s header now spawns a small rotating pair of stickers of its own on load, a random emoji and a random chaotic little tag, so it doesn&#x27;t feel like the exact same two stickers on every single page.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;I almost shipped a second &quot;screen corruption&quot; effect before catching that &lt;code style=&quot;color:var(--purple-bright);&quot;&gt;glitch.js&lt;/code&gt; already does that&lt;/b&gt; (the scroll-triggered signal tearing that&#x27;s been live for a while). Didn&#x27;t duplicate it, this pass leans on the one that already exists instead of building a competing version.&lt;/li&gt;
            &lt;li&gt;&lt;b&gt;Everything here turns off under reduced motion,&lt;/b&gt; same as always: no rift breathing, no splatter pulse, no sticker jitter or flicker.&lt;/li&gt;
          &lt;/ul&gt;</content>
  </entry>
</feed>
