# OINK 1.2.0 — Four styles, one local-first theme

> OINK 1.2.0 introduces Paper, Slate, Ink and Terminal, independent style and light/dark controls, local fonts, clearer search, consistent navigation, and safer book publishing and site maintenance.

---

LLMS index: [llms.txt](/llms.txt)

---

OINK 1.2.0 brings four visual styles to the same technical content: **Paper**,
**Slate**, **Ink** and **Terminal**. Paper becomes the default, while Slate
preserves the familiar OINK look. Readers can choose a style and light/dark
mode independently, with fonts and core scripts served from your own site.

The release also improves everyday reading and publishing: clearer Chinese
search summaries, consistent navigation and metadata, better keyboard and
clipboard behavior, and safer PDF export and maintenance tools. Existing
sites need no bulk content migration.

## At a glance {#at-a-glance}

- Four styles for the same content, with Paper as the new default and Slate available for existing sites.
- One Appearance menu for independent style and light/dark choices, with keyboard support and saved preferences.
- Local fonts, icons and core runtimes; no new font service or CDN-script dependency.
- More useful search summaries, consistent page navigation and translation-aware SEO.
- Reliable reading when scripts fail, plus fixes for copying, dialogs, math, images and diagrams.
- Safer book publishing, snapshot handling, migrations and consumer-site upgrades.

## Four styles and appearance controls {#visual-presets}

Each style changes the typography, color and component treatment while keeping
your content and navigation structure. All four have light and dark palettes.

| Style and appearance | Typography |
| --- | --- |
| **Paper**: warm paper-like surfaces, fine heading rules, framed tables and quiet shadows | IBM Plex Sans; the new default for comfortable long-form reading |
| **Slate**: the original cool technical palette, rounded surfaces, Landing grid and glow | Inter for reading and Chakra Petch display headings |
| **Ink**: black and white with red accents, strong heading rules, underlined prose links and square cards | Bold Inter headings and clear sans-serif body text |
| **Terminal**: teal links, amber accents, compact navigation and restrained terminal details | Monospace headings and controls; sans-serif prose and tables |

Paper and Slate are the standard choices. Ink and Terminal are available through
explicit configuration while their design is refined. To retain the previous
appearance when upgrading, set `params.ui.preset: slate`.

Open **Appearance** from the sun or moon button. **Style** presents four compact
icon-and-name options in two columns; **Light** offers light, dark and system
mode. The sun means the page is currently light, and the moon means it is dark.
On phones, the menu opens as a bottom sheet. Keyboard selection, Escape and
focus return follow the same controls.

Style and color mode are saved independently. Switching styles keeps the
reader near the same paragraph; navigating or reloading restores the choices.
Selecting the site's default style clears the saved style override so the
reader follows future changes to that default.

The reader's style menu remains off by default. To offer the four styles used
on this site:

```yaml
params:
  ui:
    preset: paper
    preset_menu: [paper, slate, ink, terminal]
    dark_mode: true
```

`preset_menu: true` offers Paper, Slate and the site's default preset. See the
[appearance guide](/docs/customize/brand/#visual-presets) for font and accent overrides.

The new IBM Plex Sans files are bundled with the theme, alongside the existing
fonts, icons, stylesheets and core browser runtimes. Chinese uses system font
fallbacks. Explicit font-role overrides and `typography: system` retain their
priority. Optional Giscus comments and configured analytics services keep their
external connections; preset switching adds none. Mermaid and ECharts retain
their shared light/dark palettes.

## Navigation, metadata, and images {#navigation-and-metadata}

The sidebar, previous/next links and navigation JSON now agree on hidden
subtrees and manual links. An explicitly empty navigation list warns and falls
back to the content tree, preserving a usable navigation path.

Blog pagination uses a separate canonical URL for each page. SEO language
alternates list actual translations; a language-picker fallback to a home page
is no longer presented as a translated article. Later archive pages omit
language alternates because languages may have different pagination boundaries.

Featured images consistently prefer an explicit page value, then a page-bundle
image, then an inherited value. An explicit choice remains explicit even when
it matches a cascade value. Invalid resource alt metadata warns and leaves the
authored image description intact.

## Reading and reader interactions {#rendering-and-interactions}

- **Search:** CJK queries that match only `search_keywords` show the page description or excerpt instead of a synonym list. Body matches keep their surrounding context.
- **Outline:** valid encoded fragments and literal percent signs resolve consistently, including headings near the page end.
- **Progressive enhancement:** Landing content stays visible when JavaScript is disabled or fails to load. Animated metrics retain their authored prefixes, suffixes and compact values.
- **Keyboard and copying:** clipboard fallback restores selection and focus without taking focus away from another control. Command-palette navigation recovers after focus leaves it, and page shortcuts yield to open dialogs.
- **Math and diagrams:** build-time math matches local KaTeX CSS on Hugo 0.160.1; numbered equations wrap on narrow screens. Mermaid dark labels have better contrast. Invalid PlantUML/Draw.io endpoints warn before runtimes load, and Draw.io Edit remains separate from Image Zoom.

## Repository actions {#repository-actions}

Edit, history and create-child links handle Windows source paths and external
content mounts more consistently. External mounts still require an explicit
`path_base_for_github_subdir` mapping. If a mapped path remains absolute,
drive-qualified or outside the repository boundary, source-derived actions are
omitted instead of exposing a build-machine path or linking to the wrong file.
See [repository links](/docs/customize/repository/#imported-content).

## Documentation and compatibility {#compatibility}

The English and Chinese guides cover the new styles and the corrected reading,
navigation and publication behavior. Hugo Extended **0.160.1** remains the
compatibility floor; CI uses **0.165.0**, and the module declares Go **1.27.0**.
On Hugo 0.160.x, a non-default generic `zh` alongside regional Chinese catalogs
still needs `locale: zh-CN`.

For an existing site, choose whether to adopt Paper or retain Slate, then review
copied navigation, image, math and runtime overrides against the updated theme.
No content rewrite is required. The [1.2 upgrade checklist](/docs/admin/upgrade/#preparing-1-2)
covers the configuration and validation steps.

The optional [OINK CLI](/docs/cli/) is a separate project with its own release
cycle. Ordinary Hugo builds do not require it.

## Maintenance and publication tools {#maintenance-and-publication}

Book PDF export now restricts indirect resource requests as well as direct
links. By default, media stays within the local publication origin or data
URLs. Scripts are disabled, refresh navigation is rejected, and symlinks cannot
escape the build tree. `--allow-remote-resources` permits passive HTTP(S) media;
it does not enable scripts or local-file access. Replacing an output still
requires `--force`.

Snapshot tools reject destinations that overlap site sources, theme sources,
the running tools checkout or another snapshot. This protection also covers
symlink aliases and retained output. Migration tools preserve fenced examples
nested in lists and blockquotes, including literal quote and fence markers.

## Consumer upgrade workflow {#consumer-upgrades}

The new `bin/update-consumers.py` tool helps maintainers upgrade a collection of
sites. It starts with a read-only inventory. `--write` updates module files;
`--check` verifies the exact module version and runs a warning-strict build
without inherited module replacements or workspaces.

Linked worktrees, hidden copies and non-default branches are skipped for
review. Vendor refresh is explicit, unrelated work is preserved, and a failure
at one site does not abandon the others. The tool does not commit, push or
deploy. See the [consumer maintenance contract](/docs/design/migration/#updating-consumers).

## Verification and installation {#verification}

The October 5 candidate passed theme checkers, runtime tests, the documentation
site's non-browser and browser suites, selected Hugo-floor checks, and root
and subpath EPUB/PDF checks. The
[pre-release review](/docs/design/research/2026-10-05-v1-2-release-review/)
records the exact scope, tool versions and known limits.

OINK 1.2.0 is available from [GitHub Releases](https://github.com/pgsty/oink/releases/tag/v1.2.0).
Upgrade the theme and commit the updated module files:

```bash
hugo mod get github.com/pgsty/oink@v1.2.0
hugo mod tidy
```

---

Backlinks:

- [Docs](/docs/)
