HugoBlog

hugo-theme-plano — Hugo Blog Template

By vstrofago

Plano is a Hugo blog theme with a warm paper background, a cobalt grid, and a single accent color, plus a dark variant that must be enabled manually.

Explore the design

Compare the page layouts and mobile experience. Open any screenshot for a closer look.

3 previews
Desktop homepage1 / 3
Desktop captureTop of page

Actual screenshot captured by the server browser.

All pages & views 3

Screenshots show visual appearance; interactive behavior may differ.

Recorded 2026-09-30View source

What stands out

A quick read of the recorded project description.

01

A single cobalt accent color used consistently for links, active numbers, keyword highlights, and heading underlines

02

A warm off-white background overlaid with a faint grid, with light mode as the default and only regular mode

03

The dark variant is fully isolated in assets/css/vf-dark.css, can only be enabled manually, and is recorded in localStorage

04

No build step, using native HTML, CSS, and JavaScript, with no dependency on Node or PostCSS

05

Sanchez and IBM Plex Mono fonts are self-hosted, with no requests to third-party font services

06

Interface strings live in i18n/, with English and Spanish included, and additional languages can be added

Template Details

Plano is a blog theme for Hugo whose visuals evoke a drafting table: the background is a warm off-white with a faint grid, and links, active numbers, keyword highlights, and heading underlines all use the same cobalt blue, with no other colors introduced. The theme follows a design system with explicit trade-offs, and light mode is the default and only regular mode; the dark variant is fully isolated in assets/css/vf-dark.css, activated via html[data-theme="dark"], can only be turned on by the reader clicking a button in the header, and is recorded in that device's localStorage. There are no prefers-color-scheme rules in the theme.

The theme has no build step and uses native HTML, CSS, and JavaScript. The CSS source is about 48 KB (33 KB minified), and the JavaScript is about 7 KB (3 KB minified). The Sanchez (serif) and IBM Plex Mono (labels, metadata, code) fonts are self-hosted under static/fonts/ under the SIL OFL 1.1 license, with no requests to third-party font services. The theme requires Hugo extended 0.146.0 or later because it uses the _partials and _markup directory conventions and pagerSize, and it does not need Node or PostCSS.

In terms of configuration, the theme supports multilingual sites (interface strings live in i18n/, with English and Spanish included), browser-side search based on a JSON index generated by Hugo, tag and category taxonomies, RSS output, and toggleable display items such as reading time, word count, breadcrumbs, post navigation, and table of contents. The search page requires manually adding content/<lang>/search.md and setting layout: "search". The README states that the theme has been checked in Chromium for contrast, missing assets, JavaScript errors, 390 px responsiveness, reduced-motion preference, and actual font loading; template comments are in Spanish, but user-visible strings are all managed through i18n. The exampleSite/ is a standalone bilingual site whose dates are fixed to keep the demo stable.

HugoBlog

Is it right for your project?

Use Cases

  • Building a text-focused personal blog that should have the editorial feel of paper and a grid
  • Needing a multilingual blog where interface strings and content languages are managed separately
  • Wanting to offer a dark reading mode while requiring light mode as the default and no automatic system-based switching
  • Adding a browser-side search page based on a JSON index to a Hugo site
  • Static site projects that do not want to introduce Node, a bundler, or a runtime framework

Suitable For

  • Users running Hugo extended 0.146.0 or later
  • Bloggers who prefer a single accent color and a restrained palette
  • Users who need English and Spanish interface strings, or who are willing to add i18n files themselves
  • Readers who accept manually enabling dark mode and want that choice remembered per device
  • Developers who want a theme that does not depend on npm, a bundler, or a runtime framework

Getting started & customization

Use these recorded setup notes alongside the repository instructions for your chosen version.

  1. 1

    Requires Hugo extended 0.146.0 or later; the theme uses the _partials and _markup directory conventions and pagerSize, so older versions will not work

  2. 2

    Can be installed via git submodule, Hugo module, or by copying the repository directly to themes/plano/, then declaring theme = 'plano' in the configuration

  3. 3

    The search page requires manually creating content/<lang>/search.md and setting layout: "search", and adding JSON to outputs for home

  4. 4

    Under markup.highlight, noClasses = false must be set, otherwise Chroma will inline styles and the syntax theme will not take effect

  5. 5

    The dark variant is off by default; disableThemeToggle = true can remove the toggle button and always use light mode

Read repository instructions

License & source material

Usage conditions & limitations

Free to use · keep license notice

This entry covers the free version under the MIT license in the public repository; the free scope is the code of that version and does not mean that external services or third-party assets are free.

Must comply with when using

  • The code of this version may be used, modified, used commercially, and distributed free of charge.
  • When distributing copies or substantial portions of the code, retain the original author's copyright notice and the full MIT license notice.
  • The code is provided as is; warranties and limitations of liability are governed by the original license and applicable law.

Additional costs & items to verify

  • Usage limitation: Hugo extended 0.146.0 or later is required; because the theme depends on the _partials and _markup directory conventions and pagerSize, older Hugo versions will not work.
  • Usage limitation: The search page depends on JSON in the home output; if JSON is not added to outputs for home, the search page will have no index to read.
  • Usage limitation: noClasses = false must be set under markup.highlight, otherwise Chroma will inline styles and the syntax highlighting theme will not take effect.
  • Usage limitation: The search page requires manually creating content/<lang>/search.md and setting layout: "search"; the theme will not generate that page automatically.
  • Usage limitation: The Sanchez and IBM Plex Mono fonts bundled with the theme are under the SIL OFL 1.1 license, which differs from the theme's MIT license; when replacing fonts, you must verify the license of the new fonts yourself.
  • Usage limitation: Template comments are in Spanish; user-visible strings are managed through i18n/, but template source comments are not provided in other languages.
  • Demo images, fonts, icons, and other third-party assets must be checked against their respective licenses and cannot be judged solely by the code's MIT license.
  • External services such as domains, hosting, databases, payments, or AI may incur separate charges.
View Original Text Basis

Permission is hereby granted, free of charge

Original License Text

Hugo **extended** 0.146.0 or newer (built and verified with 0.166.0). The theme uses `_partials` and `_markup` directory conventions and `pagerSize`, so older Hugo versions will not work.

Original README

`home = ['HTML', 'RSS', 'JSON']`. Without the JSON output the search page has no index to read.

Original README

`noClasses = false` under `markup.highlight`. Otherwise Chroma inlines styles and the syntax theme stops applying.

Original README

For the search page, add `content/<lang>/search.md`

Original README

Sanchez (serif) and IBM Plex Mono (labels, meta, code), both SIL Open Font License 1.1, both bundled unmodified in `static/fonts/`

Original README

Comments in the templates are written in Spanish, the author's language.

Original README
https://github.com/vstrofago/hugo-theme-plano/blob/main/LICENSEhttps://github.com/vstrofago/hugo-theme-plano/blob/main/README.md

Compiled by DeepSeek based on repository license and README ·2026-10-01. Results only cover the materials read; dependencies, images, fonts, and subsequent term changes are subject to their respective original texts.

Project checks & description sources

Template Information

Source platforms
GitHub
Documentation and maintenance reference score
More documented · 80 / 100
Technologies
Hugo
Website type
Blog
How this score is calculated

Our heuristic uses license records (up to 30), a demo link (12), a preview (10), stars (15), recorded maintenance (15), description completeness (8), feature records (5) and classification data (5). It is not a code, security or performance test, or a Google score. A link does not establish tested functionality.

What to verify for this project

Repository update recorded
2026-09-22
Screenshot last checked
2026-10-01

A demo link is listed. Check it with your own content and viewport sizes; its presence does not confirm that forms, authentication or payments work.

The catalog identifies Hugo as the primary stack. Check the actual dependency manifest and lockfile for versions and hosting requirements. These notes use recorded metadata, not a code audit or a deployment test.

Use a selection guide →

How this description was prepared

AI-assisted description based on catalog records and repository material. Repository authors are not automatically the reviewers of this description.

Automatically checked against source and license rules; no manual editorial review.

Inspect the recorded source material

SHA-256: 167b0c6bcdb941b7fe531a7da31c46a0858eebbed2472f9827b7d1d14d2ba5d5

2026-10-01T13:49:18.391Z

Source file / repository
# Plano

A Hugo theme with a drawing-table feel: warm paper, a cobalt grid, one single
accent color, and an optional dark variant that never turns itself on.

![Build example site](https://github.com/vstrofago/hugo-theme-plano/actions/workflows/build.yaml/badge.svg)

[Live demo](https://vstrofago.github.io/blog/) · [Example site](exampleSite/) ·
[MIT](LICENSE) theme, SIL OFL fonts

![Home page, light](screenshots/01-home-light.png)

## Why this theme is shaped like this

Plano comes from a small design system with opinions, and it keeps them:

- **One accent color.** Links, active numbers, keyword highlights, the rule
  under a heading: all the same cobalt. Nothing else gets to be colored.
- **Paper, not white.** The background is a warm off-white with a faint grid.
  The grid carries structure and never competes with the text.
- **Light is canonical.** The design system declares a single light mode. The
  dark variant exists because readers ask for it, is fully isolated, and is
  opt-in only.
- **No build step.** Plain HTML, CSS and JavaScript. No npm, no bundler, no
  framework at runtime. The CSS is ~48 KB in source (33 KB minified) and the
  JavaScript ~7 KB (3 KB minified).
- **Fonts are self-hosted.** No requests to third-party font services.

## Requirements

Hugo **extended** 0.146.0 or newer (built and verified with 0.166.0). The theme
uses `_partials` and `_markup` directory conventions and `pagerSize`, so older
Hugo versions will not work. Nothing else is needed: no Node, no PostCSS.

## Install

As a submodule:

```bash
git submodule add https://github.com/vstrofago/hugo-theme-plano themes/plano
```

As a Hugo module (in `hugo.toml`):

```toml
[[module.imports]]
  path = 'github.com/vstrofago/hugo-theme-plano'
```

Or just copy the repository into `themes/plano/`.

Then declare it:

```toml
theme = 'plano'
```

## Configure

The [example site](exampleSite/) is the reference configuration; the pieces the
theme actually reads are these.

```toml
baseURL = 'https://example.org/'
title = 'Your site'
theme = 'plano'
defaultContentLanguage = 'en'
defaultContentLanguageInSubdir = false

[pagination]
  pagerSize = 10

[languages]
  [languages.en]
    label = 'English'
    locale = 'en-US'
    contentDir = 'content/en'
    weight = 1
    [languages.en.params]
      description = 'Shown in the footer and in the meta description.'
      DateFormat = 'January 2, 2006'
      [languages.en.params.homeInfoParams]
        Title = 'Hero title'
        Content = 'Hero lead, written in **markdown**.'
    [[languages.en.menu.main]]
      name = 'Posts'
      url = 'posts/'
      weight = 10

[params]
  author = 'Your name'
  mainSections = ['posts']
  homeLimit = 5
  ShowReadingTime = true
  ShowWordCount = true
  ShowLastMod = false
  ShowBreadCrumbs = true
  ShowPostNavLinks = true
  ShowRssButtonInSectionTermList = true
  ShowToc = true
  TocOpen = false
  disableThemeToggle = false
  tagline = ''                     # optional: small label next to the wordmark
  socialIcons = [{ name = 'GitHub', url = 'https://github.com/you' }]

[markup]
  [markup.highlight]
    noClasses = false              # required: the syntax theme is class-based
  [markup.tableOfContents]
    startLevel = 2
    endLevel = 3

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

[outputs]
  home = ['HTML', 'RSS', 'JSON']   # JSON feeds the search index
```

Two things are easy to miss and both are required:

1. `home = ['HTML', 'RSS', 'JSON']`. Without the JSON output the search page has
   no index to read.
2. `noClasses = false` under `markup.highlight`. Otherwise Chroma inlines styles
   and the syntax theme stops applying.

For the search page, add `content/<lang>/search.md`:

```yaml
---
title: "Search"
layout: "search"
translationKey: "search"
---
```

## The dark variant

Rules, in order of importance:

- **It never turns itself on.** There is no `prefers-color-scheme` anywhere in
  the theme. Without JavaScript, or without a previous explicit choice, the site
  is light.
- **It cannot leak into the light theme.** Every dark rule lives in
  `assets/css/vf-dark.css` behind `html[data-theme="dark"]`. It redefines surface
  colors and a handful of component fills; the light theme and its tokens are
  untouched.
- **Your choice is remembered** in `localStorage` on that device, and pressing the
  toggle again returns you to light.

Set `disableThemeToggle = true` to remove the button and stay light forever.

Both modes are audited for contrast on every route (see below), so the dark
variant is not an afterthought that only looks right in a screenshot.

## Fonts

Sanchez (serif) and IBM Plex Mono (labels, meta, code), both SIL Open Font
License 1.1, both bundled unmodified in `static/fonts/` with the license text in
[`static/fonts/OFL.txt`](static/fonts/OFL.txt). To use your own, replace the files
and update `assets/css/tokens/fonts.css`; the only other place fonts are named is
the token file for typography.

## Example site and local development

`exampleSite/` is a complete bilingual site that builds on its own. The theme is
this repository, so a build needs the repo visible as `themes/plano`. The CI does
exactly this, and you can reproduce it locally:

```bash
site=$(mktemp -d)/site
mkdir -p "${site}/themes"
rsync -a --exclude .git --exclude exampleSite ./ "${site}/themes/plano/"
rsync -a ./exampleSite/ "${site}/"
hugo --source "${site}" --gc --minify --panicOnWarning --baseURL http://localhost:1314/
```

To look at it in a browser, serve the built site:

```bash
python3 -m http.server 1314 --directory "${site}/public"
```

## What was verified, and how

The theme is checked in a real browser (Chromium), not by eye:

- **Contrast**, measured on every route in both modes: each text element is
  compared against its effective background, with the threshold set by its size
  (4.5:1 normal, 3:1 large). Zero failures. This is what caught the code plate's
  punctuation at 2.88:1 and the breadcrumb's current page at 3.43:1.
- **No missing resources and no JavaScript errors** across the routes.
- **Responsive** down to 390 px with no horizontal overflow and nothing hidden.
- **Reduced motion**: with `prefers-reduced-motion: reduce` nothing is armed and
  every element sits in its final state.
- **Fonts actually load**: verified by measuring rendered text width, not by
  trusting the `@font-face` declaration.

The screenshots in this README come from the example site.

## Notes and deliberate deviations

- Comments in the templates are written in Spanish, the author's language. The
  theme itself is language-neutral: all user-facing strings live in `i18n/`
  (`en.toml`, `es.toml`, add your own).
- The source design system imported fonts from Google Fonts; this theme
  self-hosts them instead.
- The `exampleSite/` dates are fixed so the demo is stable; they are not real
  entries.

## License

Theme: [MIT](LICENSE). Fonts: SIL OFL 1.1 (see
[`static/fonts/OFL.txt`](static/fonts/OFL.txt)).

---

## En español

**Plano** es un tema de Hugo con aire de mesa de dibujo: papel cálido, rejilla
cobalto, un único color de acento y una variante oscura opcional que nunca se
enciende sola.

- **Requisitos**: Hugo *extended* 0.146.0 o superior. Sin Node, sin build step.
- **Instalación**: como submódulo (`themes/plano`), como módulo de Hugo, o
  copiando el repositorio; después, `theme = 'plano'`.
- **Claro y oscuro**: el claro es el estado canónico. El oscuro vive aislado en
  `assets/css/vf-dark.css` detrás de `html[data-theme="dark"]`, se activa con el
  botón de la cabecera y se recuerda en el dispositivo. No hay
  `prefers-color-scheme` en ninguna parte.
- **Bilingüe**: los idiomas se declaran en `hugo.toml`; las cadenas de la interfaz
  están en `i18n/` y el tema trae inglés y español.
- **Búsqueda**: en el navegador, sobre un índice JSON que genera Hugo. Necesita
  `home = ['HTML', 'RSS', 'JSON']` en `outputs`.
- **Configuración de referencia**: el [`exampleSite/`](exampleSite/) completo.
- **Licencias**: MIT para el tema; las fuentes (Sanchez e IBM Plex Mono) son SIL
  OFL 1.1 y se distribuyen sin modificar con su licencia en
  [`static/fonts/OFL.txt`](static/fonts/OFL.txt).
Report a correction

Explore similar templates

Compare previews and descriptions within the same stack and category.