Hugo theme for OmniMem — dark-first landing page + blog, self-hosted Ubuntu fonts, WCAG 2.2 AA.
  • HTML 45.3%
  • SCSS 44.2%
  • JavaScript 10.5%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ric Harvey 43098af58b
Some checks failed
Build exampleSite / build (push) Failing after 1s
Initial commit
Hugo theme for OmniMem: dark-first landing page + blog section, built
from the real omnimem.org brand (bracket wordmark, measured palette,
self-hosted Ubuntu/Ubuntu Mono), self-hosted webfonts, Font Awesome Pro
via kit script, WCAG 2.2 AA (axe-core clean across 5 page types x
dark/light), fully static (Lighthouse 99/100/96/100 on a production
build). Blog posts carry placeholder Lorem Ipsum content pending real
articles.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01M1E3ZSC4PKLgXpKA3VcogK
2026-09-08 22:12:17 +00:00
.forgejo/workflows Initial commit 2026-09-08 22:12:17 +00:00
archetypes Initial commit 2026-09-08 22:12:17 +00:00
assets Initial commit 2026-09-08 22:12:17 +00:00
exampleSite Initial commit 2026-09-08 22:12:17 +00:00
i18n Initial commit 2026-09-08 22:12:17 +00:00
images Initial commit 2026-09-08 22:12:17 +00:00
layouts Initial commit 2026-09-08 22:12:17 +00:00
static Initial commit 2026-09-08 22:12:17 +00:00
.gitignore Initial commit 2026-09-08 22:12:17 +00:00
LICENSE Initial commit 2026-09-08 22:12:17 +00:00
README.md Initial commit 2026-09-08 22:12:17 +00:00
theme.toml Initial commit 2026-09-08 22:12:17 +00:00

omnimem

The Hugo theme behind omnimem.org — a dark, technical landing page plus a blog section, built for OmniMem (a self-hosted MCP memory server) and grounded in its real brand: the <OmniMem> bracket wordmark, its measured colour palette, and self-hosted Ubuntu/Ubuntu Mono. See brand-spec.md (one level up, alongside this theme) for the full design rationale, and _design/directions/ for the three directions this was chosen from.

Screenshot

Features

  • Built for Hugo 0.146.0 and later, using the current (v0.146+) template system
  • Dark-first (the brand has no light identity of its own) with a WCAG-checked light mode behind the toggle
  • The <bracket> motif and a single restrained pulse — the theme's one signature idea, not decoration (see brand-spec.md)
  • Self-hosted Ubuntu + Ubuntu Mono webfonts — no Google Fonts request at runtime
  • Font Awesome Pro via kit script — the one deliberate external-CDN exception; see "Third-party services" below
  • Client-side search — no external service, no index shipped until someone actually searches
  • Asset pipeline: SCSS via css.Sass (Dart Sass), JS via js.Build, fingerprinted and minified
  • Responsive image rendering via Markdown image hook (WebP, multiple widths)
  • Open Graph images, including auto-generated title cards for posts with no cover
  • Full-content RSS, custom sitemap, environment-aware robots.txt
  • Pagination, tags, i18n-ready (English bundled in i18n/en.toml)
  • No client-side analytics
  • WCAG 2.2 AA pass run against the built exampleSite — see the audit notes in the PR/commit this shipped with

Requirements

  • Hugo extended 0.146.0 or later — hugo version should report extended

  • Dart Sass — Hugo extended bundles libsass, not Dart Sass, and this theme uses the latter:

    brew install sass/sass/sass     # macOS
    npm i -g sass                   # ⚠️ do NOT use this for CI/Linux — see note below
    # or download the native release: https://github.com/sass/dart-sass/releases
    

    The npm i -g sass package is the pure-JS build. It installs fine and sass --version works, but Hugo talks to Dart Sass over the embedded protocol, which the pure-JS build doesn't implement — hugo env will report sass --embedded is unavailable in pure JS mode, and every build silently falls back to the deprecated bundled libsass (which then warns on every build). On macOS with Homebrew this is a non-issue (brew install sass/sass/sass installs the native binary). On Linux/CI, download the native release directly instead — see .forgejo/workflows/hugo.yml for a working example.

    Can't install native Dart Sass at all? Set sassTranspiler = "libsass" under [params]. The build then works but prints a deprecation warning on every run (libsass was deprecated in Hugo v0.153).

  • Git

Quick start

# 1. Add the theme as a subdirectory of your Hugo site
cd /path/to/your-hugo-site
git clone https://code.squarecows.com/ric/omnimem-hugo.git themes/omnimem

# 2. Point your config at it
echo 'theme = "omnimem"' >> hugo.toml

# 3. Run
hugo server

As a git submodule

git submodule add https://code.squarecows.com/ric/omnimem-hugo.git themes/omnimem

Try the example site

The repo ships an exampleSite/ directory that builds against the theme it lives in — this is also how the real omnimem.org site is built, so it's a complete working reference, not a toy demo:

git clone https://code.squarecows.com/ric/omnimem-hugo.git
cd omnimem-hugo/omnimem/exampleSite
hugo server --themesDir ../..

Configuration

All theme-specific options live under [params] in hugo.toml. See exampleSite/hugo.toml for the full set of defaults.

Param Default Purpose
description "" Site description used in meta and SEO
author "" Author name used in footer and JSON-LD
mainSections ["posts"] Sections featured on the home page and indexed for search
showReadingTime true Show estimated reading time on posts
logo unset Path (under static/) to an image logo; falls back to the <site.Title> bracket wordmark
heroEyebrow / heroTitle / heroTitleAccent / heroLead Home page hero copy. heroTitleAccent is a word inside heroTitle to highlight in the accent colour
heroCtaPrimaryText / heroCtaPrimaryUrl Primary CTA, shown in the hero and the header
heroCtaSecondaryText / heroCtaSecondaryUrl Secondary (outline) CTA, hero only
heroTerminalTitle / heroTerminalPrompt / heroTerminalCommand / heroTerminalResult The terminal mockup beside the hero copy. Omit heroTerminalCommand to drop the panel entirely
whyEyebrow Bracket-eyebrow label above the raw .Content block between the hero and the feature grid (the theme's home page front matter, e.g. _index.md)
featuresEyebrow / featuresTitle Heading above the feature grid
[[params.features]] Array of { title, description } — one card each, no icons (see brand-spec.md on why)
fontAwesomeKitId unset Font Awesome Pro kit ID (kit.fontawesome.com/<id>.js). Leave unset to ship with no icons — nav/footer/toggle all degrade to text, nothing breaks
enableThemeToggle true Show the dark/light button. false follows the OS only (dark unless the OS explicitly asks for light — this theme is dark-first)
generateOgImages true Auto-generate an OG card for pages with no cover image
ogTextColor "#e7e9ec" Text colour on generated OG cards
rssFullContent true Put whole posts in the feed rather than summaries
rssLimit 20 Items in the feed
sitemapIncludeTerms true Include taxonomy term pages in sitemap.xml
robotsDisallow [] Extra Disallow: paths (production builds only)
sassTranspiler "dartsass" "libsass" to use the bundled transpiler instead
webfonts pre-populated Self-hosted @font-face declarations — Ubuntu + Ubuntu Mono ship by default; see below to add/replace
social Map of name = "url" for the footer social row. Recognised names (github, gitlab, forgejo, rss, mastodon, bluesky, twitter, linkedin, youtube, discord) get a Font Awesome icon when fontAwesomeKitId is set; unrecognised names still render as a text link

Pagination is set outside [params]:

[pagination]
  pagerSize = 10

TOML ordering note: every bare key = value under [params] must appear before [params.social] and the [[params.features]] / [[params.webfonts]] arrays in hugo.toml — TOML attaches bare keys to whichever table opened most recently, so a scalar param added after those blocks silently lands in the wrong place. exampleSite/hugo.toml has a comment marking the line.

Third-party services

This theme is self-hosted and dependency-free except one deliberate exception: icons load from a Font Awesome Pro kit script (kit.fontawesome.com/<kitId>.js), because Pro icons are licensed per-kit and can't be vendored into a redistributable theme. If you don't have a Font Awesome Pro kit, leave params.fontAwesomeKitId unset — every icon usage in this theme is additive (nav/footer/toggle all read fine as plain text), so nothing breaks.

Search needs the JSON output format on the home page:

[outputs]
  home = ["HTML", "RSS", "JSON"]

That emits /index.json. Remove "JSON" and the search UI renders nothing at all — it won't appear without an index behind it. Exclude a page from the index with searchExclude: true in its front matter.

Self-hosted fonts

Ubuntu and Ubuntu Mono ship pre-declared in exampleSite/hugo.toml and pre-downloaded in assets/fonts/ (latin subset, 8 files, ~240KB). To add or replace a face:

[[params.webfonts]]
  file    = "fonts/<file>.woff2"
  family  = "<Family Name>"
  weight  = "400"
  style   = "normal"
  preload = true          # body regular only

Ubuntu is licensed under the Ubuntu Font Licence 1.0 — permits embedding/redistribution as webfonts; the files aren't modified, only served.

Customising

  • Colours and type: edit the CSS custom properties at the top of assets/scss/main.scss — that :root block is the dark palette (this theme is dark-first, not light-first: see the comment there for why getting that backwards is the easiest way to end up with white-on-white). The light-mode override lives in the light-tokens mixin just below it.
  • An existing design system: map its tokens in assets/scss/_design-tokens.scss rather than renaming anything.
  • Layouts: override any partial by creating a matching file at layouts/_partials/<name>.html in your own site. Hugo's lookup order will pick your version first.
  • Render hooks: the image and link hooks live in layouts/_markup/. Override them the same way.
  • Open Graph cards: replace assets/og/base.png (1200×630) with real artwork. It must be PNG or JPEG — Hugo can't rasterise SVG.

Folder layout

omnimem/
├── archetypes/        new-content scaffolds
├── assets/            source SCSS, JS, and self-hosted fonts (compiled via Hugo Pipes)
├── i18n/              translation bundles
├── layouts/           Go templates (baseof, home, single, list + _partials, _markup, _shortcodes)
├── static/            files copied verbatim (favicon, touch-icon)
├── exampleSite/       the real omnimem.org content — home page, About, and a placeholder blog
├── images/            screenshot.png (1500×1000), tn.png (900×600)
├── theme.toml         theme manifest
├── LICENSE
└── README.md

Blog

exampleSite/content/posts/ currently holds placeholder posts with Lorem Ipsum body copy — titles say plainly what each one demonstrates (a cover image + code block, a table, a long post with a pull quote, a short note) so nothing reads as a real article. Replace them with real posts when ready; the structural variety (image, code, table, blockquote, short/long) is there so you can see every post-rendering surface the theme supports before you do.

License

MIT — see LICENSE.

Credits

Generated with hugo-theme-creator, which extends huashu-design for design direction.