[b]ack

Keyboard Navigation

2026-06

Most personal sites are pure point-and-click, and that is how the web works. But I spend most of my day in a terminal, in an editor, in a window manager where everything has a key binding. Reaching for the mouse to jump between pages on my own site felt wrong.

the design

Every navigable destination has a single letter assigned to it. The key appears inside brackets in the link label, with the rest of the word following:

[w]ork   [d]rivel   [s]helf   [c]raft

The bracket notation comes from terminal UIs, the kind you see in ncdu or btop where [q]uit or [f]ilter appear in the status bar. It makes the binding self-documenting. You don’t need to remember the shortcuts because the shortcuts are the labels.

The back link on every interior page reads [b]ack. b is an easy reach and the label is unambiguous. The shelf page adds [n]ext to cycle the quote panel.

The letter assignments are not arbitrary; they follow the same mental model as a vim leader sequence. In vim, you might hit <leader>w to jump to a window, <leader>d to open a definition. Here the leader is implicit: just the key, no prefix. w for work, d for drivel, s for shelf, c for craft. First letter of the destination, every time.

movement

Beyond page navigation, hjkl work for movement, borrowed directly from vim:

h and l as focus movement comes from btop, where the same keys cycle between panels. The pattern feels natural to me,s with different letters each mapping to familiar actions in my system configuration.

the implementation

Each page adds a keydown listener that checks e.key against a small map:

document.addEventListener('keydown', (e) => {
  if (e.metaKey || e.ctrlKey || e.altKey) return;
  const href = keys[e.key];
  if (href) window.location.href = href;
});

The modifier guard is important. Cmd+W closes a browser tab; Ctrl+D bookmarks; Alt+S does something OS-dependent. Without it, single-letter bindings would collide with half the browser’s built-in shortcuts. The guard lets the handler see only bare keypresses. hjkl are also suppressed when a text input is focused so you can still type normally.

what was left out

There’s no shortcut for external links, no tab-trap, no modal. The keyboard layer is thin on purpose: common moves feel fast, but it is not trying to replace the mouse entirely.