Files
2026-03-24 20:30:43 -04:00

11 KiB

Codex Obscura

A dark academia pixel Hugo theme with a fall color palette.

Candlelit manuscripts meet cozy stationery. Books, tea, fountain pens, and the quiet rustle of digital marginalia.


 ██████╗ ██████╗ ██████╗ ███████╗██╗  ██╗
██╔════╝██╔═══██╗██╔══██╗██╔════╝╚██╗██╔╝
██║     ██║   ██║██║  ██║█████╗   ╚███╔╝
██║     ██║   ██║██║  ██║██╔══╝   ██╔██╗
╚██████╗╚██████╔╝██████╔╝███████╗██╔╝ ██╗
 ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝  ╚═╝

Features

  • Fall color palette — deep ambers, burnt orange, rust, forest green, umber, parchment cream
  • Pixel art borders — CSS-only pixel-perfect box shadow borders on all cards and widgets
  • Blinking cursor in the site title (optional, easily disabled)
  • Dark academia typography — VT323 (pixel/terminal) for headings + Josefin Sans for body text
  • Dust mote ambient animation — soft floating particles that drift across the page like dust in a library
  • Sidebar — sys-info widget with live uptime counter, recent posts, tag cloud, and optional marginalia quote
  • Year-grouped archive — posts grouped by year in terminal ls -la style
  • Tag filtering — clickable tag chips at the top of the archive page with active highlighting
  • Post subtitles — optional per-post tagline shown on cards and single pages
  • Responsive (Mostly) — two-column desktop, stacked mobile
  • RSS feed — full RSS out of the box
  • SEO-ready — Open Graph, Twitter Card, canonical URLs
  • Syntax highlighting — via highlight.js with Common Lisp support, add more lines to layout/partials/head.html for more
  • LaTeX rendering — via KaTeX with Hugo passthrough for clean math expressions
  • Custom code blocks — shortcode with language label and optional title
  • Comments — Comentario integration (self-hosted, privacy-focused)

Installation

First run hugo new site <sitename>

cd <sitename> 
git submodule add https://git.johnabs.xyz/bs-sensei/codex-obscura-hugo-theme

Manual

Download and place the folder at themes/codex-obscura/ inside your Hugo site, which you should have made using hugo new site <sitename>


Configuration

After creating your site at from above and adding the template, you should first go to the content folder and create an about.md, resume.md, and a donate.md in your content folder or these will redirect to "Not Found". Your posts link will also redirect, unless you make a folder within content called posts and make post1.md inside it and add some text. Examples of each of these are provided below for your convenience.

A full hugo.toml example:

baseURL      = "https://yourdomain.com/"
languageCode = "en-us"
title        = "Your Site Title"
theme        = "codex-obscura"
paginate     = 8
summaryLength = 20

[markup.highlight]
  codeFences  = false   # disable Chroma — we use highlight.js instead

[markup.goldmark.renderer]
  unsafe = true # you can probably set this to false, try both. False works for me :)

[markup.goldmark.extensions.passthrough]
  enable = true
  [markup.goldmark.extensions.passthrough.delimiters]
    block  = [["$$", "$$"]]
    inline = [["$", "$"]]

[params]
  description        = "Your site description shown in the hero card."
  author             = "Your Name"
  tagline            = "a brief italicized tagline"
  sidebarQuote       = "A quote you love."
  sidebarQuoteAuthor = "The Author"
  resumePDF          = "/files/resume.pdf"
  comentarioURL      = "https://comments.yourdomain.com"

  [params.social]
    github   = "yourusername"
    mastodon = "https://mastodon.social/@you"
    email    = "you@example.com"

[[menu.main]]
  name   = "home"
  url    = "/"
  weight = 1
[[menu.main]]
  name   = "posts"
  url    = "/posts/"
  weight = 2
[[menu.main]]
  name   = "tags"
  url    = "/tags/"
  weight = 3
[[menu.main]]
  name   = "about"
  url    = "/about/"
  weight = 4
[[menu.main]]
  name   = "resume"
  url    = "/resume/"
  weight = 5
[[menu.main]]
  name   = "donate"
  url    = "/donate/"
  weight = 6

[taxonomies]
  tag      = "tags"
  category = "categories"

Creating Content

# New blog post
hugo new posts/my-entry.md

# New about page
hugo new about.md

Post front matter

---
title: "My Entry"
date: 2024-10-31
draft: false
description: "A brief description shown in meta tags."
summary: "Optional hand-written summary overriding auto-generation."
subtitle: "a quiet meditation on autumn leaves"
tags: ["autumn", "philosophy", "notes"]
author: "Archivist"
featured: true         # pins to homepage
nocomments: true       # disables comments on this post
---

The <!--more--> divider can be placed anywhere in the body to manually control where the summary cuts off:

This sentence will appear as the summary.

<!--more-->

The rest of the post continues here.

Special Pages

About

Create content/about.md with any content. Hugo uses _default/single.html.

Resume

Create content/resume.md:

---
title: "Resume"
type: "resume"
layout: "single"
resumeName: "Your Name"
resumeTitle: "Your subtitle"
email: "you@example.com"
location: "somewhere cozy"
website: "https://yoursite.com"
github: "yourusername"
resumePDF: "/files/resume.pdf"
_build:
  list: never
---

Use ## for sections, ### for job/entry titles, #### for subtitle/date lines. Place your PDF at static/files/resume.pdf.

Donate

Create content/donate.md:

---
title: "Support"
type: "donate"
layout: "single"
_build:
  list: never
kofi: "yourusername"
liberapay: "yourusername"
github_sponsors: "yourusername"
bitcoin:  "bc1qyouraddress"
ethereum: "0xyouraddress"
monero:   "4youraddress"
litecoin: "ltc1youraddress"
---

Crypto wallet cards include QR codes generated client-side in the site's amber color palette. Remove any platforms you don't use and they won't appear.


Syntax Highlighting

The theme uses highlight.js instead of Hugo's built-in Chroma for better Common Lisp support as it's my preferred language. This is already added to layouts/partials/head.html, and more can be added as you go as shown below:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/base16/monokai.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.common.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/lisp.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/python.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/r.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/julia.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/bash.min.js"></script>
<script>
  hljs.highlightAll();
</script>

Custom code block shortcode

Create layouts/shortcodes/code.html in your site root (this one you need to do!! I can't do it for you in advance):

<div class="code-block">
  {{- with .Get "lang" }}
  <div class="code-block__header">
    <span class="code-block__lang">{{ . }}</span>
    {{- with $.Get "title" }}
    <span class="code-block__title">{{ . }}</span>
    {{- end }}
  </div>
  {{- end }}
  <div class="code-block__body">
    {{ highlight (trim .Inner "\n") (.Get "lang" | default "text") "" }}
  </div>
</div>

Use it in posts:

{{< code lang="python" title="fibonacci.py" >}}
def fib(n):
    return n if n < 2 else fib(n-1) + fib(n-2)
{{< /code >}}

LaTeX

I added KaTeX to layouts/partials/head.html for math typesetting:

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.css">
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/katex.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/contrib/auto-render.min.js"
  onload="renderMathInElement(document.body, {
    delimiters: [
      {left: '$$', right: '$$', display: true},
      {left: '$',  right: '$',  display: false}
    ]
  });">
</script>

Then write inline math with $x^2$ and display math with $$\int_0^\infty e^{-x}dx$$.


Comments (Comentario)

Install and run a Comentario instance, then add to hugo.toml:

[params]
  comentarioURL = "https://comments.yourdomain.com"

Comments appear automatically on all posts. Disable per-post with nocomments: true in front matter.


Color Palette

Variable Value Use
--amber #d4a228 Primary accent
--orange #c4601c Secondary accent
--rust #8a2e08 Deep accent
--forest-light #4e7830 Terminal prompt green
--text-parchment #e8d5a3 Primary text
--bg-primary #130e07 Main background
--bg-secondary #1c1509 Card backgrounds

Override any variable by adding a static/css/custom.css and referencing it in hugo.toml:

[params]
  customCSS = ["css/custom.css"]

Typography

Role Font Notes
Terminal VT323 Headings, nav, UI elements
Body Josefin Sans Paragraph text, sans-serif
Code Courier Prime Code blocks, monospace

All loaded from Google Fonts.


File Structure

codex-obscura/
├── archetypes/
│   └── default.md
├── exampleSite/
│   ├── hugo.toml
│   └── content/
│       ├── resume.md
│       └── donate.md
├── layouts/
│   ├── index.html           # Homepage
│   ├── _default/
│   │   ├── baseof.html
│   │   ├── single.html      # Single post
│   │   └── list.html        # Archive / tag pages
│   ├── resume/
│   │   └── single.html      # Resume page
│   ├── donate/
│   │   └── single.html      # Donate page with QR codes
│   ├── tags/
│   │   └── terms.html       # Tag index
│   └── partials/
│       ├── head.html
│       ├── header.html
│       ├── footer.html
│       ├── sidebar.html
│       └── comments.html    # Comentario integration
├── static/
│   ├── css/main.css
│   ├── js/main.js           # Dust mote animation
│   └── favicon.svg
├── theme.toml
└── README.md

License

MIT — Please attribute my work to me!


"The library is infinite and the lights are always low."