As I lay in bed the other night, I became aware of an unusually-bright LED, glowing in the corner of my room1. Lying still in the dark, I noticed
that as I looked directly at the light meant that I couldn’t see it… but when I looked straight ahead – not at it – I could make it out.
In my bedroom the obstruction was the corner of my pillow, not a nondescript black rectangle. Also: my eyeball was firmly within my skull and not floating freely in a white void.
This phenomenon seems to be most-pronounced when the thing you’re using a single eye to looking at something small and pointlike (like an LED), and where there’s an obstacle closer to
your eye than to the thing you’re looking at. But it’s still a little spooky2.
It’s strange how sometimes you might be less-able to see something that you’re looking directly at… than something that’s only in your peripheral vision.
I’m now at six months since I started working for Firstup.3 And as I continue to narrow my focus on the specifics of the
company’s technology, processes, and customers… I’m beginning to lose a sight of some of the things that were in my peripheral vision.
I’ve not received quite so many articles of branded clothing and other swap from my new employer as I did from my previous, but getting useful ‘swag’ still feels cool.
I’m a big believer in the idea that folks who are new to your group (team, organisation, whatever) have a strange superpower that fades over time: the ability to look at “how you work”
as an outsider and bring new ideas. It requires a certain boldness to not just accept the status quo but to ask “but why do we do things this way?”. Sure, the answer will
often be legitimate and unchallengeable, but by using your superpower and raising the question you bring a chance of bringing valuable change.
That superpower has a sweet spot. A point at which a person knows enough about your new role that they can answer the easy questions, but not so late that they’ve become accustomed to
the “quirks” that they can’t see them any longer. The point at which your peripheral vision still reveals where there’s room for improvement, because you’re not yet so-focussed on the
routine that you overlook the objectively-unusual.
I feel like I’m close to that sweet spot, right now, and I’m enjoying the opportunity to challenge some of Firstup’s established patterns. Maybe there are things I’ve learned or
realised over the course of my career that might help make my new employer stronger and better? Whether not not that turns out to be the case, I’m enjoying poking at the edges to find
out!
Footnotes
1 The LED turned out to be attached to a laptop charger that was normally connected in
such a way that it wasn’t visible from my bed.
2 Like the first time you realise that you have a retinal blind spot and that your brain
is “filling in” the gaps based on what’s around it, like Photoshop’s “smart remove” tool is running within your head.
This is a blog post about things that make me nostalgic for other things that, objectively, aren’t very similar…
When I hear Dawnbreaker, I feel like I’m nine years old…
…and I’ve been allowed to play OutRun on the arcade cabinet at West View
Leisure Centre. My swimming lesson has finished, and normally I should go directly home.
On those rare occasions I could get away1
with a quick pause in the lobby for a game, I’d gravitate towards the Wonderboy machine. But there was something about the tactile
controls of OutRun‘s steering wheel and pedals that gave it a physicality that the “joystick and two buttons” systems couldn’t replicate.
The other thing about OutRun was that it always felt… fast. Like, eye-wateringly fast. This was part of what gave it such appeal2.
OutRun‘s main theme, Magical Sound Shower, doesn’t actually sound much like Dawnbreaker. But
both tracks somehow feel like… “driving music”?
But somehow when I’m driving or cycling and it this song comes on, I’m instantly transported back to those occasionally-permitted childhood games of OutRun4.
When I start a new Ruby project, I feel like I’m eleven years old…
It’s not quite a HELLO WORLD, but it’s pretty-similar.
At first I assumed that the tedious bits and the administrative overhead (linking, compiling, syntactical surprises, arcane naming conventions…) was just what “real”, “grown-up”
programming was supposed to feel like. But Ruby helped remind me that programming can be fun for its own sake. Not just because of the problems you’re solving or the product
you’re creating, but just for the love of programming.
The experience of starting a new Ruby project feels just like booting up my Amstrad CPC and being able to joyfully write code that will just work.
I still learn new programming languages because, well, I love doing so. But I’m yet to find one that makes me want
to write poetry in it in the way that Ruby does.
When I hear In Yer Face, I feel like I’m thirteen years old…
…and I’m painting Advanced HeroQuest miniatures6 in the attic at my dad’s house.
I’ve cobbled together a stereo system of my very own, mostly from other people’s castoffs, and set it up in “The Den”, our recently-converted attic7,
and my friends and I would make and trade mixtapes with one another. One tape began with 808 State’s In Yer Face8,
and it was often the tape that I would put on when I’d sit down to paint.
Advanced HeroQuest came with some fabulously ornate secondary components, like the doors that were hinged so their their open/closed state could be toggled, and I spent
way too long painting almost the entirety of my base set.
In a world before CD audio took off, “shuffle” wasn’t a thing, and we’d often listen to all of the tracks on a medium in sequence9.
That was doubly true for tapes, where rewinding and fast-forwarding took time and seeking for a particular track was challenging compared to e.g. vinyl. Any given song would loop around
a lot if I couldn’t be bothered to change tapes, instead just flipping again and again10.
But somehow it’s whenever I hear In Yer Face11
that I’m transported right back to that time, in a reverie so corporeal that I can almost smell the paint thinner.
When I see a personal Web page, I (still) feel like I’m fifteen years old…
…and the Web is on the cusp of becoming the hot “killer application” for the Internet. I’ve been lucky enough to be “online” for a few years by now12,
and basic ISP-provided hosting would very soon be competing with cheap, free, and ad-supported services like Geocities to be “the
place” to keep your homepage.
Nowadays, even with a hugely-expanded toolbox, virtually every corporate homepage fundamentally looks the same:
Logo in the top left
Search and login in the top right, if applicable
A cookie/privacy notice covering everything until you work out the right incantation to make it go away without surrendering your firstborn child
A “hero banner“
Some “below the fold” content that most people skip over
A fat footer with several columns of links, to ensure that all the keywords are there so that people never have to see this page and the search engine will drop
them off at relevant child page and not one of their competitors
Finally, a line of icons representing various centralised social networks: at least one is out-of-date, either because (a) it’s been renamed, (b) it’s changed its
branding, or (c) nobody with any moral fortitude uses that network any more14
But before the corporate Web became the default, personal home pages brought a level of personality that for a while I worried was forever dead.
2 Have you played Sonic Racing: CrossWorlds? The first time I played it I was overwhelmed by the speed and colours of the
game: it’s such a high-octane visual feast. Well that’s what OutRun felt like to those of us who, in the 1980s, were used to much-simpler and slower arcade games.
3 Also, how cool is it that Metrik has a blog, in this day and age? Max props.
4 Did you hear, by the way, that there’s talk of a movie adaptation of OutRun, which could turn out to be the worst
videogame-to-movie concept that I’ll ever definitely-watch.
5 In very-approximate order: C, Assembly, Pascal, HTML, Perl, Visual Basic (does that even
count as a “grown-up” language?), Java, Delphi, JavaScript, PHP, SQL, ASP (classic, pre-.NET), CSS, Lisp, C#, Ruby, Python (though I didn’t get on with it so well), Go, Elixir… plus
many others I’m sure!
6 Or possibly they were Warhammer Quest miniatures by this point; probably this memory spans one, and also the other, blended together.
7 Eventually my dad and I gave up on using the partially-boarded loft to intermittently
build a model railway layout, mostly using second-hand/trade-in parts from “Trains & Transport”, which was exactly the nerdy kind of model shop you’re imagining right now: underlit
and occupied by a parade of shuffling neckbeards, between whom young-me would squeeze to see if the mix-and-match bin had any good condition HO-gauge flexitrack. We converted the
attic and it became “The Den”, a secondary space principally for my use. This was, in the most part, a concession for my vacating of a large bedroom and instead switching to the
smallest-imaginable bedroom in the house (barely big enough to hold a single bed!), which in turn enabled my baby sister to have a bedroom of her own.
8 My copy of In Yer Face was possibly recorded from the radio by my friend ScGary, who always had a tape deck set up with his finger primed close to the record key when the singles chart came on.
9 I soon learned to recognise “my” copy of tracks by their particular cut-in and -out
points, static and noise – some of which, amazingly, survived into the MP3 era – and of course the tracks that came before or after them, and
there are still pieces of music where, when I hear them, I “expect” them to be followed by something that they used to some mixtape I listened to a lot 30+ years
ago!
10 How amazing a user interface affordance was it that playing one side of an audio
cassette was mechanically-equivalent to (slowly) rewinding the other side? Contrast other tape formats, like VHS, which were one-sided and so while rewinding there was
literally nothing else your player could be doing. A “full” audio cassette was a marvellous thing, and I especially loved the serendipity where a recognisable “gap” on one
side of the tape might approximately line-up with one on the other side, meaning that you could, say, flip the tape after the opening intro to one song and know that you’d be
pretty-much at the start of a different one, on the other side. Does any other medium have anything quite analogous to that?
11 Which is pretty rare, unless I choose to put it on… although I did overhear it
“organically” last summer: it was coming out of a Bluetooth speaker in a narrowboat moored in the Oxford Canal near Cropredy, where I was using the towpath to return from a long walk to nearby Northamptonshire where I’d been searching for a geocache. This was a particularly surprising
place to overhear such a song, given that many of the boats moored here probably belonged to attendees of Fairport’s Cropredy Convention, at which – being a folk music festival – one
might not expect to see significant overlap of musical taste with “Madchester”-era acid house music!
12 My first online experiences were on BBS systems, of which my very first was on a
mid-80s PC1512 using a 2800-baud acoustic coupler! I got onto the Internet at a point in the early 90s at which the Web
existed… but hadn’t yet demonstrated that it would eventually come to usurp the services that existed before it: so I got to use Usenet, Gopher, Telnet and IRC before I saw
my first Web browser (it was Cello, but I switched to Netscape Navigator soon after it was released).
13 On the rare occasion I close my browser, these days, it re-opens with whatever
hundred or so tabs I was last using right back where I left them. Gosh, I’m a slob for tabs.
14 Or, if it’s a Twitter icon: all three of these.
15 Of course, they’re harder to find. SEO-manipulating behemoths dominate the search
results while social networks push their “apps” and walled gardens to try to keep us off the bigger, wider Web… and the more you cut both our of your online life, the calmer and
happier you’ll be.
Clive Barker’s Imajica has long been one of my favourite fantasy novels. The heft of the single-volume edition renders it both unwieldy and
intimidating, which is probably why my most recent reading of it was only the fourth time I’ve enjoyed it from cover-to-cover. But enjoyed it I did, and I’m sure I’ll pick
it up again in a further decade or so for another adventure.
I’m aware that it draws comparison to his perhaps more-widely-read Weaveworld, but somehow that never did it for me in the same way. Perhaps my mistake was
reading Imajicafirst, way back when I was a teenager, and so satiating my appetite for “curious flawed everyman explores adjacent reality alongside magical
woman, faces horrors”; just an unfortunate coincidence that I picked up Weaveworld right after!
I also fully accept the critics who observe that it’s exceptionally drawn-out, at times. But where it does seem to drag, it does so with a certain gravity;
an inertia: the slower parts of the story are full of intention, and meaning, and – frequently – foreshadowing. I still find new expressions of its themes in
it, each time I read it. This time around, for example, I found myself finding a plethora of reflections of protagonist Gentle’s role as a forger: unable to create anything novel as an
artist (for reasons that become apparent in the long run) but only able to copy beautiful things belonging to others. This self-inflicted curse shows up again and again in innumerable
subtle ways before the truth of it is (finally, eventually – did I mention how weighty this fat book is?) exposed… and with such an epic tale it’s little wonder that it’s impossible to
remember all of the indications that preceded it!
I’ve long appreciated how Imajica plays with gender and, to a lesser-extent, relationships and sexuality, in a way that was revelatory for me on a first reading and which with
the benefit of hindsight I can see is incredibly progressive for its age. Gentle and Judith exist each to further the plot in their own ways, not as romantic “goals” for one another…
despite not only tropes in the genre but also the ways in which their characters are presented within their world – by which I mean: this isn’t a story about how they “get together at
the end”, and that subverts both the expectation of how they’re introduced in the writing and also the destinies with which their characters seem to be imbued. Pie’o’pah
presents, depending on the circumstance, as either male or female but also as some other gender entirely. Gender is a huge overarching theme, with a oppressive patriarchal
power that’s threatened by a mysterious feminine energy playing a key role that, like everything else, is quietly echoed throughout the novel.
But perhaps my favourite part of this wonderful book is its world-building, which – through the eyes of an outsider – paints a rich picture of each of several fantastical dominions.
Over the course of the adventure a character draws a map to chart the wonders of the story’s universe, but it’s ultimately incomplete (and perhaps impossible to complete). That’s what
it feels like to me as a reader, too: like being given a glimpse of a wider and even-more-wonderful world just beyond the horizon: a fantastical creation too large to ever fully
comprehend. While retaining a focus on the story of three-or-so core characters, Barker teases us with the idea that there’s “something more” just beyond our peripheral vision. And
that’s flipping amazing.
This post is also available as a video. If you'd prefer to watch/listen to
me talk about this topic, give it a look.
I am tired. For a couple of years I’ve been blaming it on iron-poor blood, lack of vitamins, diet, and a dozen other maladies. But now I’ve found out the real reason: I’m tired
because I’m overworked.
The population of the UK is 69 million1, of which the latest census has 37 million “of working age”2.
According to the latest statistics, 4,215,913 are unemployed3, leaving 32,784,087 people to do all the work.
19.2 million are in full time education4, 856,211 in the armed
forces5, and collectively central, regional, and local government employs 4.987 million6. This leaves just 12,727,876
to do all of the real work.
Long term disabilities affect 6.9 million7. 393,000 are on visas that prohibit them from working8, and 108,0859 are working their way through the
asylum process.
Of the remaining 339,791 people, a hundred thousand are in prison10 and 239,789 are in hospital11.
That leaves just two people to do all the work that keeps this country on its feet.
You and me.
And you’re sitting reading this.
This joke originally appeared aeons ago. I first saw it in a chain email in around 199612, when I adapted it from a US-centric version to a more
British one and re-circulated it among some friends… taking the same kinds of liberties with the numbers that are required to make the gag work.
And now I’ve updated it with some updated population statistics13.
12 In fact, I rediscovered it while looking through an old email backup from 1997,
which inspired this blog post.
13 Using the same dodgy arithmetic, cherry-picking, double-counting, wild
over-estimations, and hand-waving nonsense. Obviously this is a joke. Oh god, is somebody on the satire-blind Internet of 2026 going to assume any of these numbers are
believable? (They’re not.) Or think I’m making some kind of political point? (I’m not.) What a minefield we live in, nowadays.
I was having trouble visualising the dice probabilities for some Forged in the Dark-based1
RPGs2, so I drew myself a
diagram. I don’t know who, if anybody, would be interested in such a thing other than me… but that’s why we put these things online, right?
1-3: Failure – depending on the circumstances you might be
able to try again (with greater risk) and/or suffer some kind of consequence (a “harm” or “complication”).
4-5: Limited success – you succeed, but with come kind of
consequence.
6: Success – you succeed!
Multiple 6s: Critical – you succeed, and it’s more-effective
than you’d hoped or you gain some other benefit4.
If you’re playing Blades in the Dark or another Forged in the Dark-based game and find it useful to visualise how likely you are to get screwed-over by the dice…
you’re welcome!
Footnotes
1Forged in the Dark is the name of the permissively-licensed SRD originally used
for fantasy RPG Blades in the Dark, but it’s been used in plenty of other places too where its relatively fast-and-loose mechanics are best-suited. Sharp-eyed readers might
have noticed this come up in a repost from last week, too…
2 I may or may not be considering Forged in the Dark as the engine for a
prototype RPG environment I’ve been half-heartedly constructing this winter…
3 A task for which you’ve prepared and have trained, in an area in which you’re skilled,
and for which you’re well-equipped (e.g. an accomplished thief takes the time to carefully pick a basic lock using fine tools) is likely to involve rolling more dice than a
less-fortunate individual.
Over the Christmas break I dug out my old HTC Vive VR gear, which I got way back in the Spring of 2016. Graphics card technology having come a long
way1,
it was now relatively simple to set up a fully-working “holodeck” in our living room with only a slight risk to the baubles on the Christmas tree.
For our younger child, this was his first experience of “roomscale VR”, which I maintain is the most magical thing about this specific kind of augmented
reality. Six degrees of freedom for your head and each of your hands provides the critical level of immersion, for me.
And you know what: this ten-year-old hardware of mine still holds up and is still awesome!2
The kids and I have spent a few days dipping in and out of classics like theBlu, Beat Saber, Job Simulator, Vacation Simulator, Raw Data,
and (in my case3)
Half-Life: Alyx.
It doesn’t feel too heavy, but this first edition Vive sure is a big beast, isn’t it?
I’m moderately excited by the upcoming Steam Frame with its skinny headset, balanced weight, high-bandwidth
wireless connectivity, foveated streaming, and built-in PC for basic gaming… but what’s with those controllers? Using AA batteries instead of a built-in rechargeable one feels like a
step backwards, and the lack of a thumb “trackpad” seems a little limiting too. I’ll be waiting to see the reviews, thanks.
When I looked back at my blog to double-check that my Vive really is a decade old, I was reminded that I got it in the same month at Three
Rings‘ 2016 hackathon, then called “DevCamp”, near Tintern4.
This amused me, because I’m returning to Tintern this year, too, although on family holiday rather than Three Rings business. Maybe I’ll visit on a third occasion in
another decade’s time, following another round of VR gaming?
Footnotes
1 The then-high-end graphics card I used to use to drive this rig got replaced
many years ago… and then that replacement card in turn got replaced recently, at which point it became a hand-me-down for our media centre PC in the living room.
2 I’ve had the Vive hooked-up in the office since our house move in 2020, but there’s rarely been space for roomscale play there: just an occasional bit of Elite: Dangerous at my desk…
which is still a good application of VR, but not remotely the same thing as being able to stand up and move around!
3 I figure Alyx be a little scary/intense for the kids, but I could be
wrong. I think the biggest demonstration of how immersive the game can be in VR is the moment when you see how somebody can watch it played on the big screen and be fine but as soon
as they’re in the headset and a combine zombie has you pinned-down in a railway carriage and it’s suddenly way too much!
4 Where, while doing a little geocaching, I messed-up a bonus cache’s coordinate
calculation, realised my mistake, brute-forced the possible answers, narrowed it down to two… and then picked the wrong one and fell off a cliff.
I’ve found myself, unusually, with enough free time for videogaming this Christmas period. As a result I’ve played – and loved enough to play to completion – not one
but two games that I’d like to recommend to you!
Egg
Egg, released last month by Terry Cavanagh, is a frustrating but satisfying 3D puzzle platformer playable for free on the Web or downloadable for a variety of platforms.
If Getting Over It with Bennett Foddy was a story about eggs instead of a man whose legs are stuck in a cauldron…
then it’d still be much harder than Egg, which almost never made me want to throw my computer out of the window.
It’s not quite a “rage game”, because it’s got copious checkpoints, but it will cause at least a little frustration as you perform challenging timed jumps to deliver each
of your six eggs to suitable nests hidden throughout the map. But I enjoyed it: it was never too hard, and it always felt like my hard work was paid-off in satisfying
ways.
I probably spent a little over an hour lost in its retro aesthetic, and was delighted to do so: maybe you should give it a go too.
Dispatch
You probably don’t need me to introduce you to Dispatch, from AdHoc Studio, because the Internet
has gone wild over it and rightly. Available for PlayStation and Steam, it’s a narrative-driven multi-pathed game that straddles both storytelling and strategic resource management
mechanics.
And it does the best job I’ve seen at making it feel like your choices matter since Pentiment. Perhaps
longer.
For the bits in-between the strategy layer, the quicktime events, and the dialogue choices, the game seamlessly slips into pre-rendered video that provides a best-in-class
“interactive movie” experience.
The story is well-written and wonderfully voice-acted: I’d have absolutely been happy to watch this “superhero workplace comedy” as a TV show! But the way it has you second-guessing
your choices and your priorities every step of the way significantly adds to the experience.
The basic gameplay is intuitive, lightweight fun, with a couple of surprises along the way… but it’s the story that’ll keep you hooked to the end of the eighth episode. There’s a good
chance this one’s going to win a ton of awards.
It only took about 8-10 hours of my time, spread over two or three sessions, but it’s very “episodic” so if – like me – you need to be able to dip in and out of games (when life gets in
the way) it’s still a great choice. And there’s some replay-value too: I’m definitely going to run through it a second time.
So if you’ve got at-least-as-much space for videogaming in your life as I do (which isn’t a high bar), those are my two “hot picks” for the season.
But just sometimes, somebody asks2 “Yeah, but what does your birth
certificate say?”
My birth certificate says… Dan Q. Fuck the haters3.
It didn’t used to say “Dan Q”, but nowadays… yes, that’s exactly what my birth certificate says.
Y’see, I was born in Scotland, and Scottish law – in contrast to the law of England & Wales4
– permits a change of name to recorded retroactively for folks whose births (or adoptions) were
registered there.
And so, after considering it for a few months, I filled out an application form, wrote an explanatory letter to help the recipient understand that yes,
I’d already changed my name but was just looking for modify a piece of documentation, and within a few weeks I was holding an updated birth certificate. It was pretty
easy.
Somehow my modification does not make this Rick and Morty episode any more batshit-crazy than
it already was.
I flip-flopped on the decision for a while. Not only is it a functionally-pointless gesture – there’s no doubt what my name is! – but I was also concerned about what it
implies.
Am I trying to deny that I ever went by a different name? Am I trying to disassociate myself from my birth family? (No, and no, obviously.)
But it “feels right”. And as a bonus: I now know my way around yet another way for (some) Brits to change their names. Thanks to my work at FreeDeedPoll.org.uk I get an increasing amount of email from people looking for help with their name
changes, and now I’ve got first-hand experience of an additional process that might be a good choice for some people, some of the time5.
Footnotes
1 By the time you’ve got your passport, driving license, bank account, bills etc. in your
name, there’s really no need to be able to prove that you changed it. What it is is more-important anyway.
2 Usually with the same judgemental tone of somebody who insists that one’s “real” name is
the one assigned closest to birth.
3 If you’re zooming in on the details on that birth certificate and thinking “Hang on, he
told me he was an Aquarius but this date would make him a Capricon?”, then I’ve got news for you about that too.
4 Pedants might like to enjoy using the comments to point out the minority of
circumstances under which a birth certificate can be modified retroactively – potentially including name changes – under English law.
5 I maintain that a free, home-made deed poll is the easiest and cheapest way to change
your name, as a British citizen, and that’s exactly what FreeDeedPoll.org.uk helps people produce… and since its relaunch it does its processing entirely in-browser, which is totally badass from both a hosting and a user privacy perspective.
Modern CSS is freakin’ amazing. Widespread support for nesting, variables, :has, and :not has unlocked so much potential. But I don’t yet see it used widely
enough.
Suppose I have a form where I’m expecting, but not requiring, a user to choose an option from each of several drop-downs. I want to make it more visually-obvious
which drop-downs haven’t yet had an option selected. Something like this:
It’s a slightly gnarly selector, but thanks to nesting you could choose to break it into multiple blocks if you preferred.
What that’s saying is:
a <select>
that contains an <option>
where that <option> does not have a value="..."
and that <option> is currently selected
gains a dotted red outline around it
Or in short: if the default option is selected, highlight it so the user knows they haven’t chosen a value yet. Sweet!
Obviously you could expand this to have different effects for every value, if you wanted.
I can’t understate how valuable it is that we can do this in CSS, nowadays. Compared to doing it in JavaScript… CSS gives better performance and reliability and is much easier to
implement in a progressively-enhanced manner.
Here’s another example, this time using a fun “dress-up Dan” feature I from a redesign of my blog theme that I’m hoping to launch in the New Year:
If you’ve ever wanted to know what I’d look like if I were an elderly Tom Scott, my new design will answer that question!
Every single bit of interactivity shown in the video above… from the “waving” Dan to the popup menu to the emoji-styled checkboxes to the changes to t-shirt and hair
colours… is implemented in CSS.
The underlying HTML is all semantic, e.g. the drop-down menu is a <details>/<summary> pair (with thanks to Eevee for
the inspiration); its contents are checkbox and radiobutton <input>es; the images are SVGs that use CSS variables (another killer feature these years!) to specify
colours (among other things), and virtually everything else… is CSS.
Consider this:
:root{
/* Default values for Dan's t-shirt, hair, and beard colours used throughout the site: */--dan-tshirt:#c3d4d7;
--dan-hair:#3b6f8f;
--dan-beard:#896a51;
/* ...more variables... */
}
/* When the page contains a "checked" checkbox, update some variables: */
:root:has(#dan-tshirt-color-white:checked){--dan-tshirt:#c3d4d7;}
:root:has(#dan-tshirt-color-purple:checked){--dan-tshirt:#7429a8;}
/* ... */
:root:has(#dan-hair-color-natural:checked){--dan-hair:#896a51;}
:root:has(#dan-hair-color-blue:checked){--dan-hair:#3b6f8f;}
/* When "dye beard" is checked, copy the hair colour: */
:root:has(#dan-dye-beard-toggle:checked){--dan-beard:var(--dan-hair);}
The ability to set :root CSS variables, based on the status of user-controlled elements like checkboxes within the document, unlocks amazing options for interactivity. It
also works in smaller scopes like HTML Web Components, of course, for encapsulated functionality.
If you’re still using JavaScript for things like this, perhaps it’s time you looked at how much CSS has grown up this last decade or so. CSS gives you performance benefits, less
fragility, and makes it easier for you to meet your accessibility and usability goals.
You can still enrich what you create with JavaScript if you like (I’ve got a few lines of JS that save those checkbox states to localStorage so they persist
through page loads, for example).
But a CSS-based approach moves more of your functionality from the “nice to have” to “core” column. And that’s something we can all get behind, right?
An additional thing I wanted to implement – again, for the next version of my blog’s theme – was an “alt text viewer”. Mastodon has one, and it’s excellent2.
Mastodon’s viewer requires JavaScript, but I was inspired when I saw James come up with a
CSS-based version that used a re-styled checkbox.
But I wanted to do one better. Displaying alt text, too, seems like an example of what would semantically be best-represented by a
<details>/<summary> pair.
Clicking on the image shows a larger version in a lightbox; clicking on the ‘alt’ button shows the alt text… all in semantic HTML and vanilla CSS.3
My first attempt tried to put the alt-text widget inside the <summary> of the original image, but that’s an accessibility no-no, so instead I
wrap both<details> blocks (the lightbox, and the alt-text revealer) inside a container and then reposition the latter over the former.
The rest is all the same kinds of tricks I demonstrated previously, to ensure that you can click in-and-out of both in an intuitive way and that keyboard navigation works as you’d
expect.
I can’t use it on my blog yet (because if I do, it’ll probably break horribly when I add the functionality to my entire theme, later!), but I’ve put together a demonstration page that showcases the technique, plus a GitHub repo with all of the code (which is all public domain/unlicensed). Go have a
play and tell me what you think!
Footnotes
1 As a secondary goal, using <details>/<summary>
means that it’ll behave better when CSS is disabled or unavailable, which’ll make it easier to celebrate Naked CSS Day!
2 Why would I, a sighted person, need an alt text viewer, you ask? All kinds of reasons.
Good alt text is for everybody, and can help by providing context, e.g. “explaining” the joke or identifying the probably-well-known-but-I-didn’t-recognise-them subject of a
photo. Here’s some more reasons.
3 If you love owls and you love accessibility, this is the kind of example you should give
a hoot about.
This weekend, I received my copy of DOCTYPE, and man: it feels like a step back to yesteryear to type in a computer program from a
magazine: I can’t have done that in at least thirty years.
So yeah, DOCTYPE is a dead-tree (only) medium magazine containing the source code to 10 Web pages which, when typed-in to your computer, each provide you with some kind of fun and
interactive plaything. Each of the programs is contributed by a different author, including several I follow and one or two whom I’m corresponded with at some point or another, and each
brings their own personality and imagination to their contribution.
I opted to start with Stuart Langridge‘s The Nine Pyramids, a puzzle game about trying to connect all nodes in a 3×3 grid in a
continuous line bridging adjacent (orthogonal or diagonal) nodes without visiting the same node twice nor moving in the same direction twice in a row (that last provision is described
as “not visiting three in a straight line”, but I think my interpretation would have resulted in simpler code: I might demonstrate this, down the line!).
The puzzle actually made me stop to think about it for a bit, which was unexpected and pleasing!
Per tradition with this kind of programming, I made a couple of typos, the worst of which was missing an entire parameter in a CSS conic-gradient() which resulted in the
majority of the user interface being invisible: whoops! I found myself reminded of typing-in the code for Werewolves and
Wanderer from The Amazing Amstrad Omnibus, whose data section – the part most-liable to be affected by a typographic bug without introducing a syntax error – had
a helpful “checksum” to identify if a problem had occurred, and wishing that such a thing had been possible here!
But thankfully a tiny bit of poking in my browser’s inspector revealed the troublesome CSS and I was able to complete the code, and then the puzzle.
I’ve really been enjoying DOCTYPE, and you can still buy a copy if you’d like one of your own. It manages to simultaneously feel both fresh and nostalgic,
and that’s really cool.
But I’m pretty sure there are some people who’d rather receive updates to my blog via WhatsApp. And
now, they can. Here’s how I set up an RSS-to-WhatsApp gateway, in case you want to run one of your own2.
A Whapi account connected to your WhatsApp account3
– when you set up an account you’ll get a free trial; when it ends you need to find the link to say that you want to carry on with the free tier (or upgrade to the paid tier if you
expect to send more messages than the free tier’s limit)
A WhatsApp channel to which you want to push your RSS feed: I’d recommend that you make a newsletter (from the Updates tab in WhatsApp, press the kekab menu then
Create Channel) rather than a traditional group: groups are designed for multiple people to talk and discuss and everybody can see one another’s identity, but a newsletter
keeps everybody’s identity private and only allows the administrator(s) permission to post updates.
You probably want to use the kind of channel that’s for one-to-many ‘push’ communication, not a discussion group.
In Settings > Secrets and Variables > Actions, add two new Repository Secrets:
WHATSAPP_API_TOKEN: set to the token on your Whapi dashboard
WHATSAPP_CHANNEL: set to your newsletter ID (will look like 123456789012345678@newsletter) or group ID (will look
like 123456789012345678@g.us): you can get this from the Newsletters or Groups section of Whapi by executing a test GET /newsletters or GET /groups request4.
Do a test run: from the Actions tab select the “Process feeds” action and click “Run workflow”. If it finishes successfully (and you get the WhatsApp message), you’re done! If it
fails, click on the failed action and drill-in to the failed task to see the error message and correct accordingly.
By default, the processor will run on-demand and every 30 minutes, but you can modify that in.github/workflows/process-feeds.yml. It’s configured to send the single oldest
un-sent item in any of the RSS feeds it’s subscribed to, on each run (it tracks which ones it’s sent already by their guids, in a "seen": [...] array in
feeds.json): sending a single link per run ensures that WhatsApp’s link previews work as expected. At that rate, you could theoretically run it once every 10 minutes and
never hit the 150-messages-per-day limit of Whapi’s free tier5), but you’ll want to work out your own optimal rate based on the
anticipated update frequency of your feeds and the number of RSS-to-WhatsApp channels you’re running.
You can, of course, run it on your own infrastructure in a similar way. Just check out the repository to your local system with Ruby 3.2+ running, run bundle to install the
dependencies, then set up a cron job or some other automation to run ./process_feeds.rb. Doing this could be used to hook it up to your RSS feed updating pipeline, for
example, to check for new feed items right after a new post is published.
Footnotes
1 Their own incomprehensible, illogical, weird reasons.
2 I hope that the title gives it away, but you can do this completely for free.
So long as you keep your fork of the GitHub repository open-source then you can run GitHub Actions for free, and so long as you’re pushing out no more than 150 updates per day to no
more than 5 different channels in a month then you can do it within Whapi’s free tier: that’s probably fine for a personal blogger, and there’s a reasonable pricing structure (plus
some value-added extras) for companies that want to use this same workflow as part of a grander WhatsApp offering.
3 Setting this up requires giving Whapi access to your WhatsApp account. If you don’t like
the security implications of that, you could get a cheap eSIM, set that up with WhatsApp, and use that account: if you do this, just remember to “warm up” your new WhatsApp
account with some conversations with yourself so it doesn’t look so much like a spammer! Also note that the way Whapi works “uses up” one of the ~4 devices on which you can
simultaneously use WhatsApp Web/WhatsApp Desktop etc.
4 Prefer the command-line? So long as you’ve got curl and jq
then you can get a list of your newsletters (or groups) and their IDs with curl -H 'Authorization: Bearer YOUR_API_TOKEN' -H 'accept: application/json'
https://gate.whapi.cloud/newsletters?count=100 | jq '.newsletters[] | { id: .id, name: .name }' or curl -H 'Authorization: Bearer YOUR_API_TOKEN' -H 'accept:
application/json' https://gate.whapi.cloud/groups?count=100 | jq '.groups[] | { id: .id, name: .name }', respectively.
5 Going beyond the free tier would require sending one message, on average, every 9
minutes and 36 seconds.
A couple of weeks ago I blogged about setting up a PO Box and adding postal mail to the ways you can
contact me. I went for a “pay as you go” PO Box because I didn’t know if anybody would actually use it, but I’ve already received two delightful postcards and I couldn’t be more
thrilled.
The PO Box worked very well: I’m using UK Postbox principally because of their “pay as you go” rate (with a free tier in case you don’t receive
any mail at all, which I figured was a risk) but I was later pleased to discover they’re a nice company in other ways,
too. They scan the outside/one side of my mail as it arrives and I can optionally pay to scan the whole thing and/or to bundle and forward it on to me3.
I’ve started a new page to collect all the cards, including a (hopefully pretty-accessible) CSS-powered interactive “flipper” so you can turn them over, and
I’m hopeful that I might attract a few more as time goes on. Getting physical mail from “Internet friends” helps make the digital world feel a little bit smaller, and I
love it.
1 Florence’s RSS feed was missing a <![CDATA[ ... ]]> block around some
embedded HTML, which was causing the HTML to be evaluated “as if” it were XML, which – not being XHTML – it failed to do.
2 My suggestion was a variation of Derek Dingle’s Too Many Cards that I’ve been performing all over the place: it’s an immensely satisfying trick to perform, requiring a challenging but achievable set of sleights and
suitable to do without preparation and using a borrowed deck, which is pretty much the gold standard in card magic.
3 I’ve opted to have it forwarded: I’m wondering if I can combine all the postcards I get
into a single poster frame or something: maybe a double-sided one so the whole thing can be flipped to show the text, not just the fronts?
About twenty years ago, after a a tumultuouslife, Big.McLargeHuge – the shared server of several other Abnibbers and I – finally and fatally kicked the bucket. I spun up its replacement, New.McLargeHuge, on hosting company DreamHost, and this blog (and many other sites) moved over to it1.
Wow, I’d forgotten half of these websites existed.
I only stayed with DreamHost for a few years before switching to Bytemark, with whom I was a loyal customer right up until a few years
ago2, but in that time I took advantage of DreamHost’s “Refer & Earn” program, which
allowed me to create referral codes that, if redeemed by others who went on to become paying customers, would siphon off a fraction of the profits as a “kickback” against my server
bills. Neat!3
DreamHost’s referrals had a certain “pyramid scheme” feel in that you could get credit for the people referred by the people you referred.
A year or so after I switched to ByteMark, DreamHost decided I owed them money: probably because of a
“quirk” in their systems. I disagreed with their analysis, so I ignored their request. They “suspended” my account (which I wasn’t using anyway), and that was the end of it.
Right?
But the referral fees continued to trickle in. For the last seventeen years, I’ve received a monthly email advising me that my account had been credited, off the back of a
referral.
I have no explanation as to why the amount of the referral reward fluctuates, but I can only assume that it’s the result of different people on different payment schedules?
About once a year I log in and check the balance. I was quite excited to discover that, at current rates, they’d consider me “paid-up” for my (alleged) debt by around Spring 2026!
I had this whole plan that I’d write a blog post about it when the time came. It could’ve been funny!
But it’s not to be: DreamHost emailed me last night to tell me that they’re killing their “Refer & Earn” program; replacing it with something different-but-incompatible (social media’s
already having a grumble about this, I gather).
So I guess this is the only blog post you’ll get about “that time DreamHost decided I owed them money and I opted to pay them back in my referral fees over the course of eighteen
years”.
No big loss.
Footnotes
1 At about the same time I moved Three
Rings over from its previous host, Easily, to DreamHost too, in order to minimise the number of systems I had to keep an eye on. Oh, how different things are now, when I’ve
got servers and domain registrations and DNS providers all over the damn place!
2 Bytemark have rapidly gone downhill since their acquisition by Iomart a while back, IMHO.
3 Nowadays, this blog (and several of my other projects) is hosted by Linode, whose acquisition by Akamai seems not to have caused any problems with, so that’s fab.
Back before PCs were black, they were beige. And even further back, they’d have not only “Reset” and “Power” buttons, but also a “Turbo” button.
I’m not here to tell you what it did1. No, I’m here to show you how to re-live
those glory days with a Turbo button of your very own, implemented as a reusable Web Component that you can install on your very own website:
Go on, press the Turbo button and see what happens.
(Don’t press the Reset button; other people are using this website!)
If you’d like some beige buttons of your own, you can get them at Beige-Buttons.DanQ.dev. Two lines of code and you can
pop them on any website you like. Also, it’s open-source under the Unlicense so you can take it, break it, or do what you like with it.
I’ve been slumming it in some Web Revivalist circles lately, and it might show. Best Resolution (with all its 88×31s2),
which I launched last month, for example.
You might anticipate seeing more retro fun-and-weird going on here. You might be right.
2 I guess that’s another “if you know, you know”, but at least you’ll get fewer
conflicting answers if you search for an explanation than you will if you try to understand the turbo button.