Style Guide

This paragraph is the baseline. Everything else on this page should feel like it belongs next to it: same rhythm, same measure, same voice. If a new element looks out of place here, fix the component, not the content.

Heading 1 (h1)

Note: the post title already renders as the page <h1>, so inside content you should normally start at ##. This one exists so the style is defined anyway.

Heading 2 (h2)

Section-level heading. The workhorse of a blog post.

Heading 3 (h3)

Sub-section heading.

Heading 4 (h4)

Rarely needed, but styled so it never surprises you.

Heading 5 (h5)
Heading 6 (h6)

Inline text

Text can be bold, italic, bold italic, or struck through (strikethrough needs remark-gfm). Inline code looks like pnpm build, and a link looks like this. An external link and an internal link share the same style on purpose — one hover behavior to learn.

Blockquote

Design is the beauty of turning constraints into advantages.

Blockquotes can hold multiple paragraphs, and even nested elements like inline code.

Lists

Unordered:

Ordered:

  1. Clone the repo
  2. Run pnpm install
  3. Drop a .mdx file into content/posts/

Task list (needs remark-gfm):

Code block

// lib/posts.ts
export function getPost(slug: string) {
  return getAllPosts().find((p) => p.slug === slug);
}

Table

Tables need remark-gfm.

ElementComponent keyPlugin needed
Tabletableremark-gfm
Task listinputremark-gfm
Blockquoteblockquote—

Image

A placeholder image — put real files in /public/images
A placeholder image — put real files in /public/images

The caption above comes from the alt text via the custom img component.

Horizontal rule

Content before the rule.


Content after the rule.

Footnote

Footnotes also come from remark-gfm.1

MDX-only: custom components

Anything registered in the components map in page.tsx can be used inline:

Footnotes

  1. And they render at the bottom of the post automatically. ↩