Everything this template can do, on one page
This post exists to prove the rendering pipeline. Everything below is real
Markdown, rendered at build time with no client-side JavaScript involved.
## Cover images
The image at the top of this post comes from the CMS media library and is
declared in frontmatter:
“`yaml
cover: https://fangtech.in/wp-content/uploads/2026/10/sample-cover.svg
coverAlt: ‘An abstract dark grid with a single pale curve crossing it’
“`
Cover images also appear as thumbnails in post lists, and are used as the
social-sharing image on social platforms.
## Inline images
Images inside the post body work the same way. Drop the file in
`public/uploads` via the CMS and reference it by path:

Add a caption and it renders as a proper figure. Images are constrained to the
measure of the text column and given a 16:9 box so the page does not jump
around while they load.
## Tables
Technical posts always have exactly one table, and it is always unreadable by
default. This one has a sticky header row, aligned numeric columns, and it
scrolls horizontally rather than overflowing on a phone.
| Feature | Where it is set | Needs a rebuild |
| —————— | ———————– | ————— |
| Title | `src/content/blog/*.md` | Yes |
| Cover image | Frontmatter | Yes |
| Tags | Frontmatter | Yes |
| Table of contents | Generated from headings | Yes |
| Dark mode | `localStorage` | No |
| Search index | Pagefind, at build time | Yes |
| Prev / next links | Generated at build time | Yes |
## Code
Fenced blocks are highlighted at build time and wrapped, so a long line
scrolls instead of breaking the layout.
“`ts
type Post = {
id: string;
data: {
title: string;
pubDate: Date;
draft: boolean;
tags: string[];
};
};
// Drafts never reach the site, the feed, or the search index.
const published = posts.filter((p) => !p.data.draft);
“`
Inline `code` works too, and so does keyboard input like Ctrl +
K to jump to the search box.
## Blockquotes and lists
> A blockquote is set in a lighter weight with a rule down the left edge. It is
> the one piece of styling on the page that is not a hairline border.
And a nested list, to check the marker colour and spacing:
1. First item
2. Second item
– Sub-item with a nested marker
– Another sub-item
3. Third item
## A long enough post gets a table of contents
This section, plus the five above it, crosses the threshold where the sidebar
appears. Scroll down slowly and watch the current heading in the rail on the
right change weight. It is a scroll-spy with no animation — it simply stops
being bold when you move to a different section.
Short posts skip the rail entirely, because a table of contents with two
entries is worse than no table of contents at all.
## The end
There is a previous/next pair below this post, and a link back to the author.
Both are generated at build time from the same ordering used by the blog index,
so they can never disagree with it.
You must be logged in to post a comment.