Still getting back into the rhythm of working on this little site, and into posting on this little site. There’s much more to come, but I’ve been working on a couple things over the last week.

First, I’ve collapsed my home page and my erstwhile about page — the content on each page was redundant to the other’s, both had uncomfortably large photos of myself, and neither felt like they stood on their own. In short, one had to go. Besides, consolidating the two pages gave me a chance to act on some advice I got from two old friends: to write another, more professional-sounding bio for myself. I don’t know that I’ve especially succeeded at hitting that target, but I can say I hated every minute of the exercise.

(I kid, but folks I do not especially enjoy writing about myself.)

Secondly, and maybe more noticeably, I’ve restored the little ✨theme chooser✨ to the footer.1 If your browser supports the code required for it, you can choose from three options in the footer: the light, default theme; the new darker theme; and a third option to automatically switch between the two, depending on the time of day.

(That’s right. Purple.)

Mechanically, this hasn’t changed much from the old design’s theme switcher, but I did relish the opportunity to clean up my CSS a bit. It started by going through my new design, and pulling out all the individual color values into a list of custom properties:

:root {
  --color--mono-0: #000;
  --color--mono-0-10: rgba( 0, 0, 0, 0.1 );
  --color--mono-10: #1E1E1E;
  --color--mono-10-0: rgba( 30, 30, 30, 0 );
  --color--mono-10-40: rgba( 30, 30, 30, 0.4 );
  --color--mono-20: #292929;
  --color--mono-30: #404040;
  …
}

Starting here lets me build a long, flat list of color values. These design tokens are rudimentary little style primitives, all sitting outside their intended use in the design.

From there, I can then create a set of more descriptive and functional color properties:

:root {
  …
  --theme--color-bg-base: var(--color--mono-95);
  --theme--color-text-main: var(--color--mono-20);
  --theme--color-text-link: var(--color--orange-30);
}

And those more descriptive values are, in turn, what’s referenced in my CSS:

body {
  background: var(--theme--color-bg-base);
  color: var(--theme--color-text-main);
}
a {
  color: var(--theme--color-text-link);
}

This isn’t a new approach, mind. A couple years back, Henry Desroches wrote a wonderful overview of this architectural approach to design tokens. But drawing a division between a token’s value and its function makes it incredibly easy for me to spin up new site themes — like my little dark mode that just went live!

:root {
  --color--mono-80: #DFDFDF;
  --color--purple-30: #2F1F39;
  --color--blue-50: #78B0D9;
}
[data-site-theme="dark"] {
  --theme--color-bg-base: var(--color--purple-30);
  --theme--color-text-main: var(--color--mono-80);
  --theme--color-text-link: var(--color--blue-50);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-site-theme]) {
    --theme--color-bg-base: var(--color--purple-30);
    --theme--color-text-main: var(--color--mono-80);
    --theme--color-text-link: var(--color--blue-50);
  }
}

Just as with everything else about this little site, there’s a lot to finesse here — there are other token categories beyond color; as you might have gathered from my token names, there’s some palette streamlining I could potentially do; I’m considering switching back to hsl() notation for my colors, which could help with that — but this feels like a good foundation to build on.

And I have to say, it feels good to have this little worry stone back again.


  1. There must be something in the air, as Hidde just published an in-depth tutorial on how he built his new dark mode toggle. It’s very good, and worth your time. ↩︎