Skip to content
AhmadDev

Design system

Black and white, two typefaces, one grid. Everything on this site is built from the pieces below.

Principles

  • No colour in the interface

    Black, white and neutral greys. Photos stay greyscale until you point at them.

  • Two typefaces, one hand

    Geist Sans for everything people read, Geist Mono for everything people scan. Caveat appears only when the quill writes a poem.

  • One grid

    A 75rem frame with hairline edges. Every row lines up with every other row.

  • Icons, never emoji

    Remix Icon via react-icons: line icons for actions, fill icons for identity.

Colour

TokenUseLightDark
--canvasPage background#ffffff#000000
--subtleHover rows, code ground#fafafa#0a0a0a
--mutedSelected states, image wells#f2f2f2#1a1a1a
--lineHairlines and grid#ebebeb#1f1f1f
--line-strongInputs and outlines#d4d4d4#333333
--fg-3Labels and metadata#717171#8a8a8a
--fg-2Secondary text#4d4d4d#a1a1a1
--fgText and primary actions#000000#ffffff

Type

  • Display

    Geist Sans 600, -0.05em, 0.95

    Engineer.

  • Title

    Geist Sans 600, -0.04em, 1.1

    Selected work

  • Heading

    Geist Sans 600, 24px

    Three ways of looking

  • Lead

    Geist Sans 400, 18px, 1.625

    Software engineer and community builder in Lagos.

  • Body

    Geist Sans 400, 17px, 1.75

    The body of every essay, story and poem.

  • Label

    Geist Mono 400, 12px

    17 Sept 2026

  • Code

    Geist Mono 400, 14px

    const voice = 'engineer';

Marks and icons

  • Software EngineerEngineering and community work
  • DesignerDesign writing and work
  • WriterWriting and poems
  • Through my LensThe personal journal

Interface icons (line)

Wordmark

AhmadDevAhmadDevAhmadDev

Actions

Code styles

Every code block in the editor can be set to one of three styles. Paper follows the theme, terminal is always dark, grid sits on a dotted ground for specs and config.

voice.tsTypeScript
export const voices = ["engineer", "designer", "writer"] as const;
Shell
pnpm dev
# open http://localhost:3000/studio
TypeScript
export const voices = ["engineer", "designer", "writer"] as const;

Grid

Pages sit in a frame with hairline edges. Each section is a row; cells inside a row are split by hairlines, and small crosshairs mark where a row meets the frame.

.frame

.row

.cell