Refreshing a Personal Playground

Personal websites are rare territory: no clients, no analytics goals, just pure experimentation. I recently gave mine a fresh coat of paint — not a rewrite, but a series of small, satisfying upgrades. Here are the details worth sharing.

Font Pairing

The Inkwell family from Hoefler & Co. remains a favorite, and the new design leans into mixing its serif, sans-serif, weight, and case variations. But Inkwell has a distinctly playful character — too jovial for more serious articles.

Last time, I paired it with Ideal Sans, but the combination never felt quite right. This round, I switched body copy to Whitney: lighthearted enough to sit well with Inkwell, yet neutral enough to handle straightforward tone.

Rotating Colors on the Blogroll

Zebra-striping a list is classic :nth-child territory:

tr:nth-child(even) {
  background-color: var(--color-1);
}
tr:nth-child(odd) {
  background-color: var(--color-2);
}

For a repeating four-color pattern, the approach is still :nth-child trickery — select every fourth item, then offset. Using Sass with nested rules saves repetitive selectors:

li {
  &:nth-child(4n) a {
    color: $blue;
  }
  &:nth-child(4n + 1) a {
    color: $yellow;
  }
  &:nth-child(4n + 2) a {
    color: $red;
  }
  &:nth-child(4n + 3) a {
    color: $purple;
  }
}

Sass was already in the project, so there was no new tooling — I just opened CodeKit and the processing was ready. That’s how the colorful blogroll came together, four shades cycling through every list item:

And yes, blogrolls are making a comeback.

Chill YouTube Embeds

For embedded videos, I used a click-to-load technique that trades the heavy iframe for a simple static image. The interaction remains identical — click, and the player loads — but the initial page weight drops significantly since the browser never fetches the full YouTube resource set until needed.

<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/Y8Wp3dafaMQ"
  srcdoc="<style>*{padding:0;margin:0;overflow:hidden}html,body{height:100%}img,span{position:absolute;width:100%;top:0;bottom:0;margin:auto}span{height:1.5em;text-align:center;font:48px/1.5 sans-serif;color:white;text-shadow:0 0 0.5em black}</style><a href=https://www.youtube.com/embed/Y8Wp3dafaMQ?autoplay=1><img src=https://img.youtube.com/vi/Y8Wp3dafaMQ/hqdefault.jpg alt='Video The Dark Knight Rises: What Went Wrong? – Wisecrack Edition'><span>▶</span></a>"
  frameborder="0"
  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  title="The Dark Knight Rises: What Went Wrong? – Wisecrack Edition"
></iframe>

Structured Content with Custom Post Types

WordPress Custom Post Types, paired with a plugin like Advanced Custom Fields, give me predictable, structured data to work with. Looping over that output is straightforward, but the real win is flexibility: structured content opens doors for future layouts and features without reshaping the underlying data model.

Three CMS input screens: Add New Conference (with conference related fields), Add New Interview, and Add New Action Item.

Dynamic Biography Builder

The bio section is hardly sophisticated under the hood. There are 18 static <div> elements covering combinations of three lengths, two styles, and three code types. A few lines of JavaScript compute a class string from the current selections and swap visibility.

Bio generator showing HTML for my personal bio. Radio buttons next to it to change 1st to 3rd person, length, and code type of bio.

The site already used jQuery and FitVids’ jQuery variant, so I stayed with that stack. If I were rebuilding, I’d drop jQuery entirely, grab a more modern FitVids alternative, and find a way to author just a few core bios — converting formats programmatically for the rest rather than hand-writing every variant.

ztext.js in the Header

The header includes a ztext effect — the kind of subtle, dimensional motion that feels uniquely “webby.” It’s too playful for a high-traffic destination like CSS-Tricks, where time-on-site is higher and constant animation gets old. But for a personal site visited occasionally, it adds the right touch of cheerful movement.

After an upgrade to the SVG Backgrounds site, the backgrounds felt too good to pass up:

SVG backgrounds website showing off wavy dark gray lines over black, configurable through a controls panel.

The site uses background-attachment: fixed, which looks sharp. Desktop gets the slideout footer too — a fixed panel that appears on scroll — but I’m less convinced it’s earning its place here. The effect works best when the background behind it changes, and this one stays static. I’ll likely swap out the footer background or drop the effect altogether.

Generating Hover Styles with Filters

Each site section has its own accent color, and links follow those tones. Consistent blue links would be simpler, but the per-section color scheme works fine — hover and focus styles are intact. Rather than hand-crafting custom hover colors per accent, one trick handles all sections uniformly:

a:focus, .button:focus,
a:hover, .button:hover {
  filter: brightness(120%);
}

The finished touches took only a couple of hours, mostly fueled by that week’s CodePen Challenge about blogrolls. But as always with personal projects, one thing leads to another — and the playing continues.