2024 October 31 16:12

I spent the last couple of days revisiting the world of web fonts.

For several years, this site and muforth.dev have been using web fonts hosted by Google Fonts. One of the consequences of this setup is that Google gets a “ping” whenever someone visits the sites. My CSS code does an @import from a Google URL, and Google responds by returning several @font-face CSS statements, each one containing a Google (fonts.gstatic.com) URL to a web font file for the browser to download.

While I haven’t ever launched into it in earnest, de-Googling my life is always in the back of my mind. No longer giving Google metadata about my site visitors is one of the ways I can “pull the plug” on Google’s surveillance of us all.

I thought it would be fun (?) to figure out how to self-host the web fonts. Switching to self-hosting requires three steps:

Here is the @import URL I had been using for this site (I’ve added line breaks for readability):

  @import url('https://fonts.googleapis.com/css?family=\
    Encode+Sans+Condensed:400,500,600,700\
    |Encode+Sans:400,500,600,700\
    |Droid+Serif:400,400i,700,700i\
    |Fira+Mono:400,500,700&subset=latin-ext');

If you visit that URL you’ll see a bunch of @font-face statements, one for each font weight (unless the font is dynamic, but these are the exception). Here are a few examples of what is returned:

  @font-face {
    font-family: 'Droid Serif';
    font-style: normal;
    font-weight: 400;
    src: url(https://fonts.gstatic.com/s/droidserif/v19/tDbI2oqRg1oM3QBjjcaDkOr9rAA.ttf) format('truetype');
  }
  @font-face {
    font-family: 'Droid Serif';
    font-style: italic;
    font-weight: 700;
    src: url(https://fonts.gstatic.com/s/droidserif/v19/tDbX2oqRg1oM3QBjjcaDkOr4lLz5CwOnTQ.ttf) format('truetype');
  }
  @font-face {
    font-family: 'Encode Sans';
    font-style: normal;
    font-weight: 400;
    font-stretch: normal;
    src: url(https://fonts.gstatic.com/s/encodesans/v19/LDIcapOFNxEwR-Bd1O9uYNmnUQomAgE25imKSbHhROjLsZBWTSrQGGHjVtKF6A.ttf) format('truetype');
  }
  @font-face {
    font-family: 'Fira Mono';
    font-style: normal;
    font-weight: 400;
    src: url(https://fonts.gstatic.com/s/firamono/v14/N0bX2SlFPv1weGeLZDtgJv7X.ttf) format('truetype');
  }

The process of finding and downloading the fonts was more involved than I had expected. If possible I wanted to find the “authoritative” (upstream) source for each font, rather than simply manually downloading the fonts from the fonts.gstatic.com URLs, or searching on Google Fonts and downloading the fonts from there.

Google’s Droid font no longer exists; it morphed into Noto. Noto is, confusingly, available from four different sources:

After poking around the different sources, I downloaded zip archives of Noto Sans and Noto Serif from Google Fonts. These contain both variable (width and weight) and static fonts.

Encode Sans is available from the designer, Pablo Impallari, via GitHub or Google Fonts. If you want the smaller, all-in-one variable version – variable in both width and weight – you can only get it from Google Fonts. The fonts on GitHub each have a single width and weight. I downloaded a zip archive of the GitHub master branch, but I might revisit that decision and use the variable version instead.

The Fira fonts are available from Mozilla and from bBox Type, one of the original partners on the Fira project. The bBox versions have changes that aren’t in the Mozilla versions, but I have no idea what those changes are. There is also Fira Code – an unofficial fork of Fira Mono with added programming ligatures.

I decided to use the “original” versions from Mozilla. As with Encode Sans, I downloaded a zip archive of the master branch from GitHub.

In order to create my own @font-face statements I did what I always do: I wrote a Lua script!

I’m glad I went through this process. Now that I know how to do it, I can download and self-host fonts, regardless of their source.


2024 October 02 18:45

Today I discovered what I consider to be a dark pattern in Google Chrome’s account sync settings user interface.

When you turn on syncing, you have the option to use a sync passphrase. If you do this, your data is encrypted on your machine, before being sent to Google, so Google can’t read it. If you want to keep your bookmarks, history, passwords, etc private, this is definitely the way to go.

It isn’t the default, however. You have to opt in. The default is for Google to encrypt “with your Google Account” (ie, using an encryption key which they possess) – which means that they can also decrypt and read it. Given their business model, it makes sense that they don’t want you to use a sync passphrase; they want to be able to read all your data!

I set up syncing – using a sync passphrase – several years ago, and I didn’t see – or don’t remember seeing – the kind of misleading language that the interface has today:

a screenshot of Chrome's sync settings page

In particular, note the part that says “Payment methods and addresses from Google Pay won’t be encrypted.”

This suggests (to me, anyway) that if you choose to keep your data private from Google – a worthy goal – that they will leave your credit card information and billing and shipping addresses unprotected on some server somewhere, ripe for the picking by criminals. It gives you pause, so you choose not to use a sync passphrase, because this seems safer.

Let’s closely examine the first option again. If you choose this option, Google will actually only encrypt your passwords, leaving everything else unencrypted! So it’s actually more “dangerous” than using your own passphrase, but because this is the option that Google wants you to choose, there is no scary warning suggesting that your payment details will be exposed.

Whether or not you use a sync passphrase, your payment details and addresses are “unencrypted”. They need to be for Google Pay to be able to use them!

This is the essence of a dark pattern: Guiding you, often through misleading language or user interface tricks (eg, the button they want you to press is bright blue; the other button – the one you actually want – is practically greyed out), to make the choice that is better for them, and worse for you.


2024 September 27 15:22

It turns out that the weird “refresh” behavior I saw with Chrome history also occurs when scrolling in the bookmark manager. With enough folders (I’m not sure what the minimum number is that triggers this behavior, but I have about 140 top-level folders), once you scroll up or down enough, the titles of the folders that get displayed are obviously wrong. I keep the folders (and their contents) sorted, so it’s obvious when things aren’t right.

Just as with browsing history, if you click on an entry that seems wrong, it will “refresh” and re-display correctly, and sometimes the whole visible group refreshes. But scrolling “far enough” away (again, I’m not sure how far is enough) triggers the behavior.

Clearly, the bookmark and history user interfaces share some buggy display code.

I noticed this because I have been working on my bookmarking import/export code – it consumes the HTML-formatted bookmarks that the browser exports and turns them into Lua tables, which can be edited, archived, and written out again as HTML for the browser to import – and testing it on both Chrome and Firefox. This is part of my push to use Firefox “in anger” and to deprecate the use of Chrome as much as possible.

Of course, Firefox has its issues and challenges as well, but I’m enjoying it so far. I’ve been running both the Developer Edition and Nightly, and I have been surprised by how solid Nightly feels!


2024 September 23 16:58

I’m annoyed with Chrome right now.

I’ve been researching a bunch of different things over the last few weeks, and I wanted to go back and skim through my browser history to see what would be interesting to write about.

I wanted to do the same thing a few years ago, and was surprised to discover that Chrome quietly discards history older than 90 days (or something like that).

This time it’s even worse: my browser history was totally scrambled: not only did entries show up in the wrong place in the timeline, but the page titles didn’t match the URLs. Depending on how I scrolled – using the trackpad, clicking in the scrollbar, using the PgUp and PgDn keys – a single entry might fix itself, but then it would immediately get out of whack again.

I tried importing my history into Firefox and that sort of worked – the page titles at least matched the URLs – but it seemed like there was a huge chunk of time that was simply missing.

This isn’t the first time that I have been annoyed by Chrome, but since I am no longer using a Chromebook as my “daily driver” – I’m instead experimenting with using Windows 11 (on a Surface Laptop 4) and using WSL2 for my Linux adventures – I have choices.

I’m very tempted to spend a lot more time using Firefox, which has added a neat feature (starting with Firefox 120): cookie banner reduction. When sites try to pop up a cookie banner, Firefox automatically blocks it, and, if possible, automatically declines/rejects the cookies. These banners are annoying, cause prompt fatigue, and are often misleadingly designed to encourage people to accept unnecessary cookies – which will likely be used to track their browsing online.


2024 March 05 14:53

I just started reading Nassim Nicholas Taleb’s 2012 book Antifragile, and I’m finding it quite riveting. The experience reminds me of three other books that immediately grabbed me, and for the same reason: they all articulated in words and ideas feelings that I had about the world, feelings that felt true but that I had no way to express. Those three other books:

A few years ago – when I was reading everything in my local library to try to understand economics, investing, and globalization – I found the prequel to Antifragility, Taleb’s The black swan. I found one of the book’s theses – that we live in Extremistan, subject to extreme events (the titular black swans) that we have no idea how to plan for or predict – quite compelling, but I didn’t make it very far into the book before giving up. Now I wish I had persevered.

Antifragile is Taleb’s answer to black swans. The idea is that we should be building systems and living our lives in antifragile ways. Things that are antifragile get stronger when subjected to shocks, randomness, chaos, crisis, disorder, where fragile things break or unravel.

Interestingly, resilience and robustness are not the opposite of fragility, as these are things that are mostly immune to shock and disorder, but are also mostly unchanged by them, unlike the antifragile, which improve under adverse circumstances.


Read the 2023 journal.