Andrew Dorokhov

Developer blog · Own project

A custom Hugo theme that makes a 400-article knowledge base feel like a product

A dark custom theme for my development blog: Hugo templates, Tailwind 4 in Hugo's own pipeline and about 400 lines of plain JavaScript for the typing hero, the filterable knowledge graph and the scroll reveals.

articles on one set of templates
400
sections, each with its own color
30
lines of JavaScript, no UI framework
~400

The challenge

What the client needed

My development blog is where I have kept my notes since 2021: Docker, PHP, WordPress, Linux, Laravel and two dozen other topics. Over the years it grew into hundreds of articles, and the old theme showed them as a plain list of posts.

I wanted the blog to look as deliberate as the work I do for clients: a dark interface with glow and motion, a home page that shows the whole map of topics, and section and article pages that feel part of one system.

It also had to stay a static site. Writing an article means adding a Markdown file, so no page could need hand-editing when a section or an article appears, and the extra polish could not cost a heavy JavaScript bundle.

The approach

How I solved it

01

Design tokens first

The theme runs on HSL custom properties: background, surfaces and three glow colors (violet, cyan and emerald). Raised and sunken "neo" surfaces, a faint grid and a noise overlay give the dark background depth. Headings use Space Grotesk, body text Inter and code JetBrains Mono.

02

A color per section

Each section sets a color in its front matter as a Tailwind class plus a raw HSL value. The class colors the icon, and the HSL value drives the glow behind the section page, the article badge and the heading numbers. A hidden safelist prints those classes into the HTML, so Tailwind's build stats keep them in the CSS.

03

A knowledge graph from front matter

At build time Hugo writes every section with its icon, color, filter tags, order and articles into a small data object on the home page. A plain JavaScript module turns it into a filterable grid (backend, frontend, devops) with staggered cards and a detail view that slides in out of a blur, with no API and no extra request.

04

Tailwind 4 inside Hugo

Styles go through Hugo's own css.TailwindCSS function, and the class list comes from hugo_stats.json, so the CSS holds only the classes the templates use. Cache busters rebuild it when templates or the Tailwind config change. In production CSS and JavaScript get minified, fingerprinted and an SRI integrity hash.

05

Motion in plain modules

Eight ES modules, bundled by Hugo's js.Build on esbuild, handle the typing line and the parallax hero, scroll reveals on IntersectionObserver, the header dropdown and the animated mobile menu. The header menus and the articles index are generated from the sections, sorted by article count or by the order set in front matter.

06

Contact form without a backend

The consultation form posts to Netlify Forms with fetch, with a honeypot field against bots. Project-type buttons fill a hidden field, and a success panel replaces the page reload. The site itself builds and deploys on Netlify.

In motion

Highlights

01

A hero that types and fades

The headline and stats fade in one after another while the terminal line types itself out. On scroll the background moves slower than the page and the hero fades away.

Home page loading: the hero fades in, the terminal line types 'Systems Architect & Engineering Leader', then the page scrolls and the hero fades out over a slower background.
02

The knowledge graph

A filter rebuilds the grid with staggered cards. A card opens the section with its articles sliding in one by one, and the back button returns to the grid.

The Frontend filter is clicked and the grid redraws, the JavaScript card opens a list of JavaScript articles, rows highlight under the pointer, and Back returns to the grid.
03

Articles that reveal as you read

Each block of an article fades up as it enters the viewport. An IntersectionObserver adds the class once, so the page stays still on the way back.

Scrolling through the Docker Compose article: the table of contents, numbered headings and code blocks fade in as they reach the viewport.

See it in action

The product

The hero: gradient headline, typed terminal line and a grayscale portrait.
A section opened in the knowledge graph, with its articles numbered in its color.
The index of every section and article, built from the content tree.
A section page with a contents list and the section's glow.
Article typography: numbered headings, inline code and code blocks.

The outcome

What the client got

  • 400 articles in 30 sections run on the same templates; a new section needs a folder and a few lines of front matter to appear in the graph, the menu and the index.
  • The home page shows the whole map of topics, and any article is two clicks away from it.
  • Every section has its own color, and it follows the reader from the section page to each of its articles.
  • The effects run on about 400 lines of JavaScript with no UI framework, and the CSS carries only the classes the templates use.
  • Contact requests arrive through Netlify Forms, with no server to maintain.

Need something similar built?

Send a short brief about your project. Within 24 hours you get an estimate or a clear next step, even if we don't work together.