McGarrah Technical Blog

The Small Things: Polish Features That Make a Jekyll Blog Feel Professional

· 8 min read

Nobody visits a blog because it has a print stylesheet. Nobody subscribes because the 404 page has a haiku. But these small touches signal that the site is maintained, that someone thought about the details, and that the content is worth the reader’s time.

Here are six features that each took less than a day to implement but collectively transformed this blog from a default Jekyll template into something that feels intentional.

Dark/Light Theme

The blog automatically matches the reader’s operating system preference — dark mode on dark systems, light mode on light systems. No toggle button, no JavaScript, no cookie to remember the choice.

Implementation

The entire dark mode is a single CSS media query in _sass/basic.sass:

@media (prefers-color-scheme: dark)
  body
    background: $dark
    color: $light

The $dark and $light variables come from the Contrast theme’s SASS variable system. The theme was designed with dark mode support from the beginning (the original author, Niklas Buschmann, added it in December 2019), but it needed maintenance as I added features.

The Mermaid Dark Mode Fix

When I added Mermaid diagram support in September 2025, the diagrams rendered with a white background in dark mode — a blinding white rectangle in an otherwise dark page. The fix was detecting the color scheme in JavaScript and passing it to Mermaid’s initialization:

const isDarkMode = window.matchMedia &&
  window.matchMedia('(prefers-color-scheme: dark)').matches;
mermaid.initialize({
  startOnLoad: true,
  theme: isDarkMode ? 'dark' : 'default'
});

The Google Custom Search widget also needed dark mode styling (_sass/google-search.sass), and the Giscus comment widget gets it for free via the preferred_color_scheme theme setting.

Why No Toggle?

Some blogs add a manual dark/light toggle button. I chose not to because:

The Contrast theme originally had a dark_theme: true/false config option for a site-wide override. I removed that in favor of the automatic approach.

Technical blog posts get printed. People print Proxmox walkthroughs to have next to the server, or save Ceph commands as PDF references. The default Jekyll output looks terrible when printed — navigation bars, comment widgets, and copy buttons all show up on paper.

Implementation

The print stylesheet (_sass/print.sass, added September 11, 2025) is 134 lines that handle three things:

1. Hide non-content elements:

@media print
  nav, aside, footer, .giscus, .page__comments,
  .btn-copy, .gcse-search, header nav,
  .taxonomies-list, .more
    display: none !important

2. Reset to print-friendly typography:

  body
    background: white !important
    color: black !important
    font-family: "Times New Roman", serif !important
    font-size: 12pt !important
    line-height: 1.4 !important

3. Make links useful on paper:

Printed pages can’t be clicked, so links need to show their URLs. The stylesheet appends the URL after each link text so the reader can type it in.

The SASS Circular Dependency

Adding the print stylesheet triggered a SASS circular dependency nightmare — the same day I added it, I had to restructure the entire SASS architecture to eliminate circular imports. That story is told in SASS Circular Dependency Nightmare.

Custom Error Pages with Haiku

GitHub Pages serves a generic error page by default. Custom error pages are a small touch that shows the site is maintained and gives lost visitors a way back.

404: Page Not Found

---
permalink: /404.html
title: "404: Page not found"
layout: default
sitemap: false
---

<article>
  <header><h1><a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-404-not-found"
    target="_blank">404 Not Found</a></h1></header>
  <p>
    <i>You step in the stream,</i><br>
    <i>but the water has moved on.</i><br>
    <i>This page is not here.</i><br>
  </p>
</article>

500: Internal Server Error

<p>
  <i>Server, dark within,</i><br>
  <i>Unexpected fault appears,</i><br>
  <i>Try again, please wait.</i><br>
</p>

Design Decisions

The 404 page went through four commits between 2020 and 2024, mostly simplifying it from the original theme’s version down to the haiku format.

Author Bio

Every post ends with an author bio section — a short paragraph with credentials and links to professional profiles. This was added on April 2, 2026 as part of E-E-A-T improvements for AdSense approval.

Implementation

The bio lives in _includes/author-bio.html:

<div class="author-bio">
  <strong>About the Author:</strong>
  <a href="/about/">Michael McGarrah</a> is a Cloud Architect with 25+ years
  in enterprise infrastructure, machine learning, and system administration.
  He holds an M.S. in Computer Science (AI/ML) from Georgia Tech and a B.S.
  in Computer Science from NC State University, and is currently pursuing an
  Executive MBA at UNC Wilmington.
  <span class="author-links">
    <a href="https://www.linkedin.com/in/michaelmcgarrah/" rel="me">LinkedIn</a> ·
    <a href="https://github.com/mcgarrah" rel="me">GitHub</a> ·
    <a href="https://orcid.org/0000-0001-8935-1293" rel="me">ORCID</a> ·
    <a href="https://scholar.google.com/citations?user=Lt7T2SwAAAAJ" rel="me">Google Scholar</a> ·
    <a href="/resume/">Resume</a>
  </span>
</div>

Why It Matters

The bio includes dark mode support via SASS theme variables and is automatically included in every post via the post.html layout.

Archive Page

The archive page at /archive/ provides a chronological listing of every post. It’s the simplest navigation feature on the site — just titles and dates, sorted newest first.

History

The archive page has the longest history of any feature on this blog:

It works alongside the tag pages (/tags/), category pages (/categories/), and the paginated homepage to give readers multiple ways to find content. The archive is the “just show me everything” option.

Favicon

The blog has a basic favicon.ico file at the site root. It’s the minimum viable favicon — a single .ico file that browsers pick up automatically without any <link> tags in the HTML.

This is one of the items still on the TODO list for improvement — a proper favicon set would include multiple sizes (16x16, 32x32, 180x180 for Apple Touch), PNG format, and a site.webmanifest file. But the basic .ico works and prevents the 404 that browsers generate when they request /favicon.ico and find nothing.

Update: This has since been addressed — you will see an upcoming favicon post shortly.

The Compound Effect

None of these features would justify a blog post on their own. But together they create a compound effect:

Each feature took less than a day. The total investment was maybe a week across two years. The return is a site that feels maintained and intentional — which matters more than any individual feature.


About the Author: Michael McGarrah is a Cloud Architect with 25+ years in enterprise infrastructure, machine learning, and system administration. He holds an M.S. in Computer Science (AI/ML) from Georgia Tech and a B.S. in Computer Science from NC State University, and is currently pursuing an Executive MBA at UNC Wilmington. LinkedIn · GitHub · ORCID · Google Scholar · Resume