Nocturne

The tokens, type, and machinery this whole site is built from. Dark is the canonical design; light exists for daylight. Flip the theme and this page re-renders itself in it.

palette

Surfaces, ink, and accents. Hex values follow the theme you are currently reading in.

tags

Each tag draws a syntax colour, brand-faithful where that was free.design gets the comment colour on purpose — it isn’t a language, it’s a comment on languages. Every value clears 4.5:1 against the canvas in both themes.

type

Two families, two jobs, neither doing both. JetBrains Mono owns the chrome, the headings and the code — it is the one actually running in Ghostty. Geist keeps the prose, because 117,000 words of monospace is a tax on the reader.

JetBrains Mono · display

Terminally driven, Laravel inspired

Geist · body

So I’ve taken the last month or so to completely rethink my workflow for Laravel development, and it turned out to be my entire editor.

JetBrains Mono · chrome

~/blog · 2026-01-22 · 8 min · laravel

components

The post card, in both states the schema allows — hero image present, and the tag-tinted plate that stands in when it isn’t.

Code blocks read as buffers, labelled by language.

test('parses markdown docs', function () {
    expect($rows)->toHaveCount(1);
});
We have Herd at home. The Herd at home: a pile of nix expressions and a suspicious amount of confidence.

provenance

Nocturne started as a hand-built palette on the old Laravel site, picked by eye with no reference. It landed within a couple of hex digits of the tokyonight colorscheme that had been open in the editor the whole time. Left column is what got picked; right is what it was quietly copying.

The config that made it true:

require("tokyonight").setup({
    style = "night",
    styles = { floats = "transparent", sidebars = "transparent" },
    transparent = true,
})

vim.cmd([[let $BAT_THEME = 'tokyonight']])

colorscheme tokyonight

how it’s built

Astro, static output, no adapter, deployed to Cloudflare. Content is markdown in git and filenames are slugs. Every number here was measured from dist, not estimated.

JavaScript bundles
0 — no framework, no external script files
Inline script, heaviest page
2,600 bytes — search + tag filter, theme resolution, theme toggle
CSS, whole site
27.9 KB — one system, Tailwind utilities
Fonts
2 files, 59 KB — self-hosted, latin subset
Images
93 — sharp-optimised to webp at build time
Degrades without JS
All posts visible, dark theme intact — both scripts are progressive enhancement

by the numbers

Posts
33
Words
117,047
Span
7 years
First
Oct 2019

The tag breakdown, in the tag colours. Read top to bottom and it’s the arc: .NET, then the framework years, then Rust, then Laravel.