A field guide to this blog

Markdown stays simple while code, diagrams, optimized images, and fullscreen tools arrive progressively.

This post is a compact proof that the site stays simple at the authoring layer while still being pleasant to read. Everything starts as Markdown and frontmatter in the repository; the reading experience progressively adds syntax highlighting, diagrams, optimized images, and fullscreen viewers where they earn their place.

An open notebook with system sketches beside a terminal

The image above is an article-owned WebP. It is lazy-loaded, has meaningful alternative text, and keeps its intrinsic dimensions to avoid layout shift.

A few words before the widgets

The writing should work without JavaScript. A normal external link remains a normal link, while strong emphasis, gentle emphasis, and inline const details = 'small but useful' stay deliberately quiet.

Good publishing tools get out of the way of the sentence. The richer parts should explain something better than prose can.

That also means ordinary lists are still just Markdown:

  • A repository is the CMS.
  • Frontmatter carries dates, description, and pinning.
  • Fenced blocks declare their own language.
    • The page keeps wide content inside the viewport.
    • Fullscreen is available when reading needs more room.
  1. Write an index.md beside any article assets.
  2. Preview the page locally.
  3. Let the checks validate frontmatter, fences, and drawings before commit.

Code is source, not a screenshot

Language names are preserved from each fence, highlighted at build time, and shown in the toolbar. Short blocks stay compact:

type Feature = 'markdown' | 'code' | 'diagram'

const enabled = new Set<Feature>(['markdown', 'code', 'diagram'])

export const supports = (feature: Feature) => enabled.has(feature)

Long lines do not force the page wider. They remain readable in their own horizontal scroller and become easier to inspect in fullscreen:

curl --fail-with-body --silent --show-error --request POST https://example.test/api/publish --header 'content-type: application/json' --data '{"title":"A field guide to this blog","status":"draft","features":["markdown","mermaid","excalidraw","responsive-images","fullscreen-code"]}'

In fullscreen, code receives sticky line numbers and a copy button that copies source without those numbers. The viewer title includes the actual language, for example code · typescript.

A small comparison

Capability Authoring format Reader enhancement
Text Markdown Semantic HTML and linked headings
Code fenced block Highlighting, scrolling, fullscreen, copy
Diagram Mermaid or Excalidraw fence Rendered graphic with pan and pinch zoom
Image local Markdown image Responsive WebP and lazy loading

Tables retain their own horizontal scroll area on narrow screens, rather than widening the whole page.

Mermaid for precise flows

Use Mermaid when the diagram is better expressed as a small declarative graph. It keeps the source reviewable in Git and inherits the site’s restrained dark theme.

flowchart LR
  A[Markdown] --> B[Validate]
  B --> C[Build]
  C --> D[Read]
  D --> E{Need detail?}
  E -->|yes| F[Open fullscreen]
  E -->|no| D

The rendered diagram can be opened fullscreen, then panned, pinched, wheel-zoomed, reset, or closed with Escape.

Excalidraw for loose thinking

When the point is a sketch rather than a strict graph, an Excalidraw scene can live directly in a fence too. The scene below is JSON in Git, rendered as an SVG in the browser, and gets the same fullscreen treatment.

{
  "type": "excalidraw",
  "version": 2,
  "source": "https://excalidraw.com",
  "elements": [
    {
      "id": "idea-box",
      "type": "rectangle",
      "x": 40,
      "y": 60,
      "width": 170,
      "height": 80,
      "angle": 0,
      "strokeColor": "#1e1e1e",
      "backgroundColor": "transparent",
      "fillStyle": "solid",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 1,
      "opacity": 100,
      "groupIds": [],
      "frameId": null,
      "index": "a0",
      "roundness": { "type": 3 },
      "seed": 19,
      "version": 1,
      "versionNonce": 201,
      "isDeleted": false,
      "boundElements": null,
      "updated": 1,
      "link": null,
      "locked": false
    },
    {
      "id": "idea-text",
      "type": "text",
      "x": 78,
      "y": 88,
      "width": 94,
      "height": 25,
      "angle": 0,
      "strokeColor": "#1e1e1e",
      "backgroundColor": "transparent",
      "fillStyle": "solid",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 0,
      "opacity": 100,
      "groupIds": [],
      "frameId": null,
      "index": "a1",
      "roundness": null,
      "seed": 20,
      "version": 1,
      "versionNonce": 202,
      "isDeleted": false,
      "boundElements": null,
      "updated": 1,
      "link": null,
      "locked": false,
      "text": "an idea",
      "fontSize": 20,
      "fontFamily": 3,
      "textAlign": "center",
      "verticalAlign": "middle",
      "containerId": null,
      "originalText": "an idea",
      "autoResize": true,
      "lineHeight": 1.25
    },
    {
      "id": "arrow",
      "type": "arrow",
      "x": 230,
      "y": 100,
      "width": 130,
      "height": 0,
      "angle": 0,
      "strokeColor": "#1e1e1e",
      "backgroundColor": "transparent",
      "fillStyle": "solid",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 1,
      "opacity": 100,
      "groupIds": [],
      "frameId": null,
      "index": "a2",
      "roundness": { "type": 2 },
      "seed": 21,
      "version": 1,
      "versionNonce": 203,
      "isDeleted": false,
      "boundElements": null,
      "updated": 1,
      "link": null,
      "locked": false,
      "points": [[0, 0], [130, 0]],
      "lastCommittedPoint": null,
      "startBinding": null,
      "endBinding": null,
      "startArrowhead": null,
      "endArrowhead": "arrow"
    },
    {
      "id": "article-box",
      "type": "rectangle",
      "x": 380,
      "y": 60,
      "width": 170,
      "height": 80,
      "angle": 0,
      "strokeColor": "#1e1e1e",
      "backgroundColor": "transparent",
      "fillStyle": "solid",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 1,
      "opacity": 100,
      "groupIds": [],
      "frameId": null,
      "index": "a3",
      "roundness": { "type": 3 },
      "seed": 22,
      "version": 1,
      "versionNonce": 204,
      "isDeleted": false,
      "boundElements": null,
      "updated": 1,
      "link": null,
      "locked": false
    },
    {
      "id": "article-text",
      "type": "text",
      "x": 405,
      "y": 88,
      "width": 120,
      "height": 25,
      "angle": 0,
      "strokeColor": "#1e1e1e",
      "backgroundColor": "transparent",
      "fillStyle": "solid",
      "strokeWidth": 1,
      "strokeStyle": "solid",
      "roughness": 0,
      "opacity": 100,
      "groupIds": [],
      "frameId": null,
      "index": "a4",
      "roundness": null,
      "seed": 23,
      "version": 1,
      "versionNonce": 205,
      "isDeleted": false,
      "boundElements": null,
      "updated": 1,
      "link": null,
      "locked": false,
      "text": "share it",
      "fontSize": 20,
      "fontFamily": 3,
      "textAlign": "center",
      "verticalAlign": "middle",
      "containerId": null,
      "originalText": "share it",
      "autoResize": true,
      "lineHeight": 1.25
    }
  ],
  "appState": { "viewBackgroundColor": "#ffffff" },
  "files": {}
}

How the pieces fit together

Writing begins as a small Markdown document with a little metadata: a title, a description, and dates. The server turns that into a complete page, so the words arrive immediately and remain readable even when a reader has JavaScript turned off.

The richer bits arrive only where they are useful. Snippets receive language-aware highlighting; Mermaid and Excalidraw load their respective libraries only on pages that contain a diagram; each source image becomes one efficient WebP and waits until it is near the viewport. Fullscreen is an optional reading mode, not a different kind of page.

The funny side effect is that this article is both a guide and a living smoke test. If a reader can scroll this post, inspect a snippet, open a drawing, and zoom a diagram, the important publishing paths are working together.

What stays intentionally boring

The important contract is still small: content is versioned, dates are validated, image assets are generated before publication, and readers can consume the page without needing a JavaScript application. Rich blocks are an enhancement, not a new publishing system.

If you find a rough edge, this post is the place to check it first.

fullscreen