Root "dev" script uses concurrently to run both apps with labeled,
color-coded output ([site]/[cms]) instead of needing two terminals.
The per-app dev:site/dev:cms scripts stay for when you only want one.
References: pixperk.tech (dark, warm off-white text, serif-italic +
mono mixed typography, personal dashboard modules) and mcyoung.xyz
(meta line with reading time, subtle accent underline on titles).
- src/styles/tokens.css: dark-first color palette with a warm-paper
light mode (data-theme override + prefers-color-scheme, toggle wins
either direction), fluid clamp() type scale, spacing/radius scale.
- Fonts: Fraunces (display/headings, italic), Newsreader (body,
long-form readability), JetBrains Mono (nav/meta/code) — all
self-hosted via @fontsource, continuing the mono choice already
used in the legacy OG-image pipeline.
- Base.astro rewritten: real header/nav with active-link state, a
theme toggle (persisted to localStorage, no-flash inline script),
footer with social links (ported from zola.toml), replacing the
scaffold placeholder.
- Reading time: toml-content-loader.ts computes wordCount/
readingMinutes from the raw body at load time, surfaced in the
writings list and detail meta line.
- Bug fix: the marked heading renderer was using raw token.text for
both the visible heading and the TOC, so a heading like
"**Registers**" rendered literal asterisks instead of bold — now
renders inline tokens properly and strips markdown for the
plain-text TOC label/slug.
Verified in-browser (light + dark) across home, a migrated writing
with TOC/headings, bookshelf, and 404.
scripts/migrate-posts-to-writings.mjs converts all 20 posts under
content/posts/ into the new writings schema — normalizes dates to
bare TOML local-dates, converts the one unambiguous Zola shortcode in
use (youtube embeds) to a plain <iframe>, and strips the now-meaningless
{% raw %}/{% endraw %} escape tags. content/posts/ itself is untouched;
this only adds content/writings/*.
Also generates 301 redirects from the old /posts/<slug>/ URLs to the
new /writings/<slug>/ ones into sws.toml, inside marker comments so
re-running the script regenerates that block idempotently instead of
duplicating it.
Two posts (from-c-to-machine-code, self-hosting-gitea-and-mirroring-github)
use note/tip/warning/danger callout shortcodes that have no Astro
equivalent yet — flagged by the script rather than guessed at, since
that needs a real component once the design system exists.
Verified: astro check clean, full site builds (80 pages, all real
migrated posts render), redirect generation confirmed idempotent
across repeated runs.
- src/site.config.ts: minimal site metadata (title, description,
base URL, nav, tag descriptions) ported from the legacy zola.toml
as a placeholder pending real design/copy.
- RSS (@astrojs/rss) and JSON Feed endpoints, sitemap
(@astrojs/sitemap), robots.txt.
- Base.astro: meta description (site-wide default or per-page
override via llms_description/description), RSS/JSON feed
<link rel=alternate>, and a webmention endpoint link (plumbing
only — needs the domain registered on webmention.io to do
anything).
- toml-content-loader.ts: marked renderer now assigns heading ids
and collects them into rendered.metadata.headings, so
render(entry) exposes headings the same way a built-in Markdown
loader would.
- Writing detail page: table of contents, prev/next navigation,
series-nav (uses the existing extra.series/series_index fields),
and tag-overlap related posts.
- Tags index + per-tag pages, tag links wired in from writing cards.
- Pagefind: indexes the build output as part of `pnpm build`
(astro build && pagefind --site dist), plus a /search/ page using
Pagefind's default UI.
Verified: astro check clean, full build succeeds (feeds/sitemap/
pagefind all generate correctly), and manually exercised /search/
(real query, highlighted results) and /tags/ in a browser against
the built site.
Adds slug (uid) fields to all four content types so Strapi documents
can be matched to files deterministically, plus:
- apps/cms/src/utils/content-file.ts: read/write/delete the +++ TOML
frontmatter files, using smol-toml's TomlDate so dates round-trip as
bare local dates (matching the legacy Zola format), not quoted
datetime strings.
- apps/cms/src/utils/content-sync.ts: per-type frontmatter <-> Strapi
field mappings, a boot-time importer that upserts every content/
file into Strapi by slug, and a Document Service middleware that
writes any create/update/delete made through Strapi straight back
to the same files.
Strapi's SQLite DB is now genuinely a disposable cache: content/
stays buildable and readable with Strapi entirely absent, and
restarting Strapi rebuilds its DB from content/ with no duplicates
(matched by slug).
Verified end-to-end: fresh boot imports all seed files once; a second
boot re-imports idempotently (0 created, all matched by slug); create/
update/delete through the content-manager API all correctly write to
and remove the corresponding file on disk.
Adds a custom Astro loader that reads the Zola-style TOML frontmatter
(+++ ... +++) directly, so content/ stays the single source of truth
with no YAML conversion step. Defines writings/portfolio/bookshelf/
blogs collections and basic list/detail pages for each, rendering the
seed entries end-to-end (verified in-browser via `pnpm --filter site
dev`). This is the first runnable MVP: home, writings list + post
detail, portfolio, bookshelf (books and papers), and curated blogs
all render from real content/ files.
Set up a pnpm workspace with apps/site (Astro) and apps/cms (Strapi,
SQLite-backed) as the foundation for the new digital-legacy site.
Switches package management to pnpm and adds Biome for linting/
formatting, replacing npm/no-linter setup. Existing Zola site stays
in place for now and will be migrated/removed progressively.
- new paper/ink palette with single red accent, replacing catppuccin
- self-hosted IBM Plex Serif (display) + Source Serif 4 (body), drop Outfit
- rebuilt homepage masthead, numbered post index, navbar with active states
- switch syntax highlighting + utterances to gruvbox, synced via postMessage
- remove terminal/404 easter egg chrome, clean up remaining inline styles
- fix stray syntax.css link causing a 404