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 in globals.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. Honours prefers-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.md is plain Markdown where every ## heading is 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 ArticleView variant:
    • Projects (doc) keep the full set — Copy page, View as Markdown, aA text 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: just aA and 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: aA text 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.
  • 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 returns updatedAt / editUrl so 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 ⌘K and 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 its alt as a <figcaption>; an image whose title is "wide" (e.g. ![Caption](/img.jpg "wide")) 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 a p override in components/markdown.tsx with styling in the .md block of app/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 the kazanska photo set ~80% (14.7 MB → 2.9 MB) into public/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 (linkStyle with a hex or a var(--token), so a tinted edge still flips with dark mode) and a How colours work section documenting the COLORS map in lib/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_MARK in lib/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 ⌘K badge are gone (the shortcut still works); a Search tooltip stays.
  • Bottom-right corner repurposed. The contact (Mail) shortcut is replaced by a Sparkle icon — an inert placeholder for the upcoming AI chat tool, with a Soon tooltip 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: auto via a new data-context="page" hook in globals.css). The narrow projects column stays left-aligned, and read mode is unchanged.

Notes

  • Docs refreshed. README.md and CLAUDE.md were 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, Sparkle bottom-right), and the news / tags / roadmap / ⌘K search / [[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 under content/news/ with a date and its own single category in frontmatter (a taxonomy distinct from project tags), plus an optional excerpt. 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 #category under 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 ⌘K search and [[wiki-links]]. A content/news/_template.md scaffold (ignored by the reader, like any _-prefixed file) makes adding a post a copy-paste away. news sits in the nav between projects and tags.

Changed

  • /tags is now a filterable browser. Instead of a tag cloud linking out to a separate page per tag, /tags lists 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 (new hooks/use-filter-param.ts, shared components/filter-chips.tsx).

  • One tag namespace + type markers. Tags (#) are no longer project-only: news posts can carry tags: too, and a tag spans both — /tags, a tag's count, and ⌘K all include projects and posts alike (a post page shows its #tags under 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_MARK in lib/tags.ts). The ⌘K palette 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 plain hover: tie on specificity, so wrapping the dim in can-hover: (@media (hover: hover)) let it win on source order. The hovered override now stacks group-hover:hover for a higher specificity that reliably beats the dim.

0.5.0 — 2026-06-04

Added

  • Roadmap page — a new /roadmap document (in the nav between informations and changelog) 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 / an npm create package). 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 as var(--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.ts strips the generated SVG's <style> block — which carried a Google Fonts @import and global text {} / 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 in components/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 aA control (between the "View as Markdown" toggle and the prev/next arrows) that bumps the rendered .md body up a step (~14px → ~16px) for more comfortable reading on large displays. Only the content scales — the surrounding chrome stays put. The choice persists to localStorage and is restored before first paint, so it carries across pages and reloads without a flash.

Notes

  • Every font size in .md is now expressed in em off a single base, scaled by a --reading-scale token (html[data-reading]) — the whole article grows from one number in app/globals.css. New hooks/use-reading-size.ts holds the toggle state; a tiny inline script in app/layout.tsx applies the saved size before paint.

0.3.0 — 2026-06-03

Added

  • Tags — projects can now carry a tags list in their frontmatter. Tags render as #tag chips 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 its summary), 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.ts holds the fs-free slugifyTag() so the slug helper can be shared with Client Components; lib/content.ts stays server-only.
  • New lib/remark-wikilink.ts holds the [[wiki-link]] remark plugin. With the wiki resolver reading content, components/markdown.tsx is 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 .md body, 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 .md content at build (/search-index.json, prerendered) and fetched lazily on first open; ⌘K/Ctrl+K and / 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-highlight at 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 internal node prop is now stripped before the DOM).

Notes

  • New dependencies: rehype-highlight, rehype-autolink-headings, remark-github-blockquote-alert, and cmdk (shadcn command).

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 .md file under content/, read at build time (gray-matter frontmatter + react-markdown with GitHub-flavored Markdown). Drop a file in content/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.