Changelog
All notable changes to boilerplateau are recorded here. The format follows Keep a Changelog, and the project uses Semantic Versioning.
Unreleased
Added
-
Pixel tree (nav column). A little pixel-art tree now lives near the foot of the nav column, quietly shedding leaves — a reproduction of the tree on emmanuelhong.com. No canvas and no particle library: the tree is a plain
<img>(public/strom-small.png) and every leaf is a 4px<span>on CSS keyframes (components/pixel-tree.tsx+ the "Pixel tree" block inglobals.css). Hovering rustles the crown and shakes a few leaves loose; click and hold, and the release springs the tree back with a burst of leaves sized by how long it was held. Honoursprefers-reduced-motion(the leaves simply stay put — hidden). -
FAQ page (
/faq). A minimalist questions-and-answers section in the Thinking-Machines mould: each question is a single-line row with a+on the far right that opens an accordion to reveal the answer (the+rotates to a×). It stays true to "content is just Markdown" —content/faq.mdis plain Markdown where every## headingis a question and the prose beneath it is the answer (any length, full Markdown: lists, links,[[wiki-links]], code). A build-time splitter (lib/faq.ts) turns that into native<details>rows (components/faq.tsx), so there's no client JS, the content sits in the static HTML (accessible +⌘K-searchable), and the open/close + expand animation are pure CSS. Wired into the nav, the[[faq]]wiki-link resolver, and search.
0.9.0 — 2026-06-08
Changed
- Page controls now fit the content type. The header/footer chrome that used
to be one fixed bundle on every project and post is now split by what a page is
for, driven by an
ArticleViewvariant:- Projects (
doc) keep the full set — Copy page, View as Markdown,aAtext size, prev/next‹ ›, and a "Last updated · Edit on GitHub" footer. The source is the point on a docs page (the styleguide / diagrams pages lean on "View as Markdown"). - News posts (
article) are for reading: justaAand the prev/next arrows (header chip + foot pager). "View as Markdown", "Copy page", and the "Last updated · Edit on GitHub" footer are gone — a post already shows its published date under the title. - Top-level pages (
page— information, contact, roadmap, changelog) gained the reader chrome they lacked:aAtext size plus a "Last updated · Edit on GitHub" footer, without the source toggles or series arrows. (Fulfils the roadmap note to extend "Edit on GitHub" + "Last updated" to these pages.) - Home stays bare — pure content, no chrome.
- Projects (
- The shared "Last updated · Edit on GitHub" footer is now one component
(
components/article-footer.tsx), de-duplicated out of the project and news pages.getPage()now also returnsupdatedAt/editUrlso the standalone pages can render it.
0.8.0 — 2026-06-08
Added
- Zoomable content images (lightbox). Standalone images in Markdown now open
full screen on click — an in-page overlay, not a new tab. The page settles
behind a faint, theme-aware scrim (white wash in light mode, dimly visible
underneath), the open photo is square-cornered with its caption shown beneath,
and it closes on a borderless
×, Esc, or a click beside the photo. Built on the radix Dialog primitive (components/zoomable-image.tsx), the same package behind⌘Kand the mobile drawer, so it gets focus-trap and scroll-lock for free. This is the "image zoom" long noted on the roadmap. - Captioned figures, full-bleed wide figures, and galleries. The Markdown
pipeline now groups standalone images into
<figure>s: a single image gets itsaltas a<figcaption>; an image whose title is"wide"(e.g.) breaks past the reading measure; and several images in one paragraph render as a gallery grid. Wide figures are sized with a container query against the real content area (md-flow, which excludes the nav and the "on this page" rail), so they run markedly wider than the text yet never overflow into either. All markdown-native — no MDX, handled in apoverride incomponents/markdown.tsxwith styling in the.mdblock ofapp/globals.css. - Image optimizer script.
scripts/optimize-images.mjs(sharp) resizes a folder of photos to a sane web size (long edge ≤ 2000px, mozjpeg q80 / palette PNG). Used to shrink thekazanskaphoto set ~80% (14.7 MB → 2.9 MB) intopublic/kazanska-optimized/. Pre-optimizing keeps the plain<img>pipeline, so it spends zero Vercel image-optimization quota. - Demo post
content/news/kazanska.md— a short photo walk exercising the wide figures, gallery, and lightbox against real content.
0.7.0 — 2026-06-05
Added
- Diagrams reference (
/projects/diagrams) — a kitchen-sink page covering every Mermaid diagram type the renderer supports (flowchart, state, sequence, class, ER, and XY charts), each baked to a theme-reactive SVG at build time. Includes a Coloured edges example (linkStylewith a hex or avar(--token), so a tinted edge still flips with dark mode) and a How colours work section documenting theCOLORSmap inlib/mermaid.ts. Sits beside the styleguide in the project index.
Changed
- News categories are now marked with a tilde (
~meta) instead of the pilcrow (¶);CATEGORY_MARKinlib/tags.ts. Purely visual — slugs and stored data are unchanged. - Column 2 (the project index) is now scoped to the projects pages. It only
renders on the landing (
/) and inside a project (/projects/[slug]), reinforcing that the middle column is the projects. Everywhere else (news, tags, informations, roadmap, changelog, contact) the frame is just nav + content, and the bottom-left control degrades from the three-step focus cycle (all → index → reader) to a plain nav toggle (hide ↔ show). Desktop only; the mobile drawer still lists projects as before (it's the only path to them). - Search trigger is now just the magnifier — the "Search" label and the
⌘Kbadge are gone (the shortcut still works); aSearchtooltip stays. - Bottom-right corner repurposed. The contact (
Mail) shortcut is replaced by aSparkleicon — an inert placeholder for the upcoming AI chat tool, with aSoontooltip and no behaviour yet. Contact remains reachable from the nav. - Reading measure is centered on the 2-column pages. Off the projects pages
(news, tags, informations, roadmap, changelog, contact) the wide content column
used to pin the 72ch measure to the left edge, leaving a void on the right; it
now centers (
margin-inline: autovia a newdata-context="page"hook inglobals.css). The narrow projects column stays left-aligned, and read mode is unchanged.
Notes
- Docs refreshed.
README.mdandCLAUDE.mdwere brought back in line with the app — native system fonts (not Geist), column 2 scoped to the projects pages, the corner controls (search top-right,Sparklebottom-right), and the news / tags / roadmap /⌘Ksearch /[[wiki-links]]/ mermaid features.
0.6.0 — 2026-06-04
Added
- News / blog (
/news) — a reverse-chronological feed of shorter writing, separate from the projects index. Each post is a Markdown file undercontent/news/with adateand its own singlecategoryin frontmatter (a taxonomy distinct from projecttags), plus an optionalexcerpt. The index lists every post (title · date · excerpt · "read more") under a category filter row. Categories are marked with a pilcrow (¶meta) rather than the#used for project tags, so the two taxonomies read as distinct at a glance; picking a category filters the list in place and reflects the choice in the URL (/news?category=<slug>), so a filtered view stays shareable without leaving the page or losing the static render. Each post page (/news/<slug>) shows its date and a clickable#categoryunder the title — a link back to that filtered list (the "path back") — plus the same header controls as projects (Copy page, View as Markdown,aA, prev/next) and a "Last updated" + "Edit on GitHub" footer. Posts and categories are folded into⌘Ksearch and[[wiki-links]]. Acontent/news/_template.mdscaffold (ignored by the reader, like any_-prefixed file) makes adding a post a copy-paste away.newssits in the nav betweenprojectsandtags.
Changed
-
/tagsis now a filterable browser. Instead of a tag cloud linking out to a separate page per tag,/tagslists matching projects and news posts (grouped) under the same filter row as/news; picking a tag filters in place via/tags?tag=<slug>. The per-term routes (/tags/[slug]and/news/category/[slug]) are gone — the in-page filter replaces them, and both search and the project tag chips now point at the filtered URLs. The filter stays fully static: the whole list ships in the prerendered HTML, and the active term is read from / written to the URL query on the client (newhooks/use-filter-param.ts, sharedcomponents/filter-chips.tsx). -
One tag namespace + type markers. Tags (
#) are no longer project-only: news posts can carrytags:too, and a tag spans both —/tags, a tag's count, and⌘Kall include projects and posts alike (a post page shows its#tagsunder the title beside its¶category). Each content type now reads with its own glyph so the taxonomies don't blur:#tag,¶news category/article,⚹project (TAG_MARK/CATEGORY_MARK/PROJECT_MARKinlib/tags.ts). The⌘Kpalette stamps each result with its marker, giving a uniform row that still tells a project from an article at a glance.
Fixed
- Nav hover-dim — the link under the cursor stayed dimmed instead of going
back to full strength. In Tailwind v4
group-hover(via:where(.group)) and a plainhover:tie on specificity, so wrapping the dim incan-hover:(@media (hover: hover)) let it win on source order. The hovered override now stacksgroup-hover:hoverfor a higher specificity that reliably beats the dim.
0.5.0 — 2026-06-04
Added
-
Roadmap page — a new
/roadmapdocument (in the nav betweeninformationsandchangelog) sketching the high-level direction: the gap to a full docs platform, split into an "old way" of classic docs features and a "new way" AI assistant over the content, plus a parallel track for turning the engine into a reusable template (GitHub template /degit/ annpm createpackage). It is deliberately high-level — each topic still needs its own deeper write-up. Wired into search and[[wiki-links]]like every other page. -
Mermaid diagrams — a ```mermaid fenced block now renders to an SVG at build time (via
beautiful-mermaid), baked straight into the static HTML: no client bundle, no headless browser. Colours are passed asvar(--token)references, so a single diagram flips with light/dark automatically like the rest of the UI. See the new "Diagrams" section in the styleguide.
Notes
lib/mermaid.tsstrips the generated SVG's<style>block — which carried a Google Fonts@importand globaltext {}/svg {}selectors — and re-injects its derived variables plus the Geist font inline on the root<svg>, scoping everything to the one diagram (no webfont, no bleed onto the page's other SVGs). The fence is detected server-side incomponents/markdown.tsx; an invalid diagram falls back to a plain code block.
0.4.0 — 2026-06-04
Added
- Reading size toggle — each project header gains an
aAcontrol (between the "View as Markdown" toggle and the prev/next arrows) that bumps the rendered.mdbody up a step (~14px → ~16px) for more comfortable reading on large displays. Only the content scales — the surrounding chrome stays put. The choice persists tolocalStorageand is restored before first paint, so it carries across pages and reloads without a flash.
Notes
- Every font size in
.mdis now expressed inemoff a single base, scaled by a--reading-scaletoken (html[data-reading]) — the whole article grows from one number inapp/globals.css. Newhooks/use-reading-size.tsholds the toggle state; a tiny inline script inapp/layout.tsxapplies the saved size before paint.
0.3.0 — 2026-06-03
Added
-
Tags — projects can now carry a
tagslist in their frontmatter. Tags render as#tagchips under the project title (visible in both the rendered and raw views) and link to a new set of pages:/tags— a count-sorted index of every tag, reachable from the nav./tags/<slug>— every project carrying that tag (with itssummary), statically generated for the union of all tags. Tags are lowercased and de-duplicated by slug at build time, and folded into the search index, so a tag name surfaces both the projects that use it and the tag's own page in⌘K.
-
Internal links /
[[wiki-links]]— reference any other page by its filename:[[field-notes]]links to it using that page's title, and[[field-notes|custom text]]sets the label. Resolved wiki-links render as a subtle grey chip (no underline, no colour) so they read as references at a glance. Names resolve at build (matched by slug, so[[Field Notes]]works too); an unknown target is warned about in the build log and rendered as a struck-through chip. All internal links — wiki or plain[text](/projects/x)— now navigate client-side through Next<Link>instead of a full page reload.
Notes
- New
lib/tags.tsholds thefs-freeslugifyTag()so the slug helper can be shared with Client Components;lib/content.tsstays server-only. - New
lib/remark-wikilink.tsholds the[[wiki-link]]remark plugin. With the wiki resolver reading content,components/markdown.tsxis now server-only.
0.2.1 — 2026-06-02
Added
- "View as Markdown" + "Copy page" — each project header gains a chip that
copies the page's Markdown source and a toggle that swaps the rendered article
for its raw
.mdbody, beside the prev/next arrows. The rendered view stays server-built; the toggle is client-side only.
0.2.0 — 2026-06-02
A documentation-leaning release. The reading shell from 0.1.0 picks up the
"doc-site" primitives — search, syntax highlighting, callouts, anchors — while
keeping the same content-is-the-product model: everything is still a plain
.md file, read and baked at build time, no runtime services.
Added
- Site search (
⌘K) — a command palette over every page and project. The index is built from the.mdcontent at build (/search-index.json, prerendered) and fetched lazily on first open;⌘K/Ctrl+Kand/open it. The trigger lives in the top-right corner, where the clock used to be. - Syntax highlighting — fenced code blocks are coloured by
rehype-highlightat build time (baked into the HTML, no client cost), with a restrained palette and a separate dark-mode variant. - Copy button on code blocks — appears on hover, copies the exact source.
- Admonitions — GitHub alert syntax (
> [!NOTE],[!TIP],[!IMPORTANT],[!WARNING],[!CAUTION]) renders as styled callouts. See the style guide. - Heading anchors — a
#surfaces in the margin on heading hover; clicking links straight to that section (rehype-autolink-headings). - Reading progress bar — a thin bar pins to the bottom edge and fills as you scroll, but only on pages long enough to scroll and only after you start.
- Per-page metadata — pages now emit a
<meta name="description">from their frontmatter (summary/subtitle). - "Last updated" + "Edit on GitHub" — a footer on each project, with the file's last commit date (read from git at build) and a direct edit link.
Changed
- The top-right clock was replaced by the search trigger.
Fixed
- Rendered links no longer carry a stray
node="[object Object]"attribute (react-markdown's internalnodeprop is now stripped before the DOM).
Notes
- New dependencies:
rehype-highlight,rehype-autolink-headings,remark-github-blockquote-alert, andcmdk(shadcncommand).
0.1.0 — 2026-06-02
First tagged version. The site began on 2026-05-29 as a minimal, markdown-driven personal site — three columns (nav · project index · content), styled after shadcn/ui. This release rounds it out with the reading and navigation features that make long-form content comfortable.
Added
- Markdown content pipeline — every page is a plain
.mdfile undercontent/, read at build time (gray-matterfrontmatter +react-markdownwith GitHub-flavored Markdown). Drop a file incontent/projects/, push, and it ships. - Three-column shell — fixed nav, a resizable project index, and the
content column; the split persists to
localStorage, and collapses into a drawer on mobile. - View modes — one corner control cycles all columns → hide nav → read mode, progressively focusing on the text.
- Reading measure — body text is capped at a comfortable line length (72ch), relaxed to 90ch and centered in read mode.
- "On this page" outline — a pinned table of contents with scroll-spy that
highlights the section you are reading; it appears only when a page has enough
headings. Heading anchors are generated by
rehype-slug. - Previous / next paging — arrows beside the title and labelled chips at the
foot of each project, ordered by frontmatter
order. - Automatic dark mode — follows the OS via
prefers-color-scheme; no toggle, every token flips in CSS. - Changelog page — this file, readable at
/changelog.
Notes
- Stack: Next.js 16 (App Router), TypeScript, Tailwind v4, shadcn/ui (radix),
native system fonts. Statically generated and deployed on Vercel on every
push to
main.