Commit Graph
13 Commits
Author SHA1 Message Date
andwati 0644dcf253 Add sticky sidebar TOC and widen the page for large screens
Writings detail pages now show the table of contents as a sticky
sidebar once there's room (>=74rem viewport), sharing its markup with
the existing inline TOC via a new TocList.astro so neither copy drifts.
Below that breakpoint it falls back to the original inline list.

Bumped .container--wide 64rem -> 76rem (home, bookshelf, and now
writings detail) so big monitors use more of the screen. The prose
column itself stays capped at 42rem for readability; the extra room is
what makes space for the TOC gutter. Verified at 390/900/1180/1920px.
2026-09-01 09:27:10 +03:00
andwati 27e53993d6 Swap shiki for highlight.js's core build for syntax highlighting
Shiki pulls in a WASM oniguruma engine and bundled theme/grammar JSON
for two full themes; highlight.js's core build plus only the 11
languages content actually uses is much thinner for the same job here.
Token colors now come straight from the design tokens (--accent,
--text-muted, ...) instead of shiki's dual-theme CSS vars, so they
already switch with the site's theme with no extra [data-theme] rules.
2026-09-01 09:20:12 +03:00
andwati 74a7f80b29 Render legacy callout shortcodes, add code syntax highlighting
Converts the note/tip/warning/danger `{% <tag> %}...{% </tag> %}` blocks
the posts→writings migration script left untranslated into styled
.callout markup (toml-content-loader.ts's renderCallouts(), styled in
global.css to match the new design system).

Also wires shiki into the same markdown pipeline for fenced code block
highlighting (github-light/github-dark, switched by the same
[data-theme]/prefers-color-scheme pattern tokens.css already uses).

Also records the Three.js centerpiece's perf budget check in TODO.md:
scene is trivially light (well under 10k triangles, 100+fps uncapped);
the ~130KB gzip payload is three.js core itself, not a tree-shaking gap
(verified named imports change nothing - sideEffects:false already lets
Rollup shake fully), and the script is a deferred module that doesn't
block first paint. No code changes needed there.
2026-09-01 09:14:29 +03:00
andwati c035aca132 Add OG image auto-generation for writings, portfolio, and bookshelf
Replaces the legacy Zola script, which was hard-coded to the retired
"CASE FILE" branding, with scripts/generate-og-images.astro-site.mjs
built on the new design system's dark palette + Fraunces/JetBrains Mono.
Base.astro now renders og:image/twitter:image from a per-page ogImage
prop, wired into the writings and bookshelf detail pages.

Uses static-weight Fraunces/Newsreader font packages rather than the
variable fonts the site ships elsewhere, since satori's opentype.js
parser throws on their fvar table.
2026-09-01 08:59:42 +03:00
andwati f5cc3a2144 Add the Three.js constellation centerpiece and redesign the homepage
Data model: nodes are real content entries (writings, portfolio,
bookshelf), edges are shared-tag connections — the same relationship
"related posts" already uses, drawn instead of listed. No decorative
or fake data.

- src/lib/constellation-data.ts: builds the node/edge graph from the
  actual collections at build time.
- src/lib/constellation-scene.ts: vanilla Three.js scene (no
  framework) — fibonacci-sphere layout, auto-rotation, pointer
  raycasting with a title tooltip, click-through to the entry's page.
  Honors prefers-reduced-motion (skips rotation and the spring-eased
  entrance, which reuses src/lib/spring.ts) and checks WebGL support,
  falling back to a plain count for browsers/settings that lack it.
- src/components/Constellation.astro: wires it up, serializing the
  graph as inline JSON for the client script to consume.
- Homepage rebuilt around it: hero constellation above a 3-column
  dashboard (latest writings/portfolio/bookshelf), using a new `wide`
  layout variant on Base.astro (dashboard needs more than the 42rem
  article width).

Also: removes "life and beliefs" from all site copy (site.config.ts,
the llms.txt generator + its output) per request — description is
now "Computer science and mathematics."

Verified in-browser: real WebGL scene renders with correctly
positioned/colored nodes and edges, hover shows the right title via
raycasting, layout holds at the new wide container width.
2026-08-31 08:12:35 +03:00
andwati bf29139cef Check off design system items in TODO 2026-08-31 08:04:11 +03:00
andwati 454e3459a1 Annotate remaining TODO items that need input vs. infra access 2026-08-30 19:19:27 +03:00
andwati 2fdd0052b5 Extend llms.txt to all content types; fix a gitignore bug
scripts/generate-llms.astro-site.mjs covers writings, portfolio,
bookshelf, and blogs (unblocked now that site.config.ts exists from
the feeds/meta work), wired into apps/site's build script.

Also fixes .gitignore: the bare `public` pattern (meant to ignore the
Zola build's root-level output directory) was matching at any depth,
so apps/site/public/ and apps/cms/public/ were being silently
excluded from every commit despite `git add` reporting them as
staged for directory adds (the ignore-file warning only surfaces for
an explicitly named path, not a recursive directory add — easy to
miss). Scoped to `/public` so only the root output dir is ignored.
Picks up robots.txt, the Astro scaffold's favicon, llms.txt, and
Strapi's own public/robots.txt, none of which were actually tracked
until now.
2026-08-30 19:18:43 +03:00
andwati 4fa9715ebf Check off carried-over content features and Pagefind in TODO 2026-08-30 19:04:53 +03:00
andwati 7b857d4be7 Note why OG-image and llms.txt extension are blocked, not skipped 2026-08-30 18:53:24 +03:00
andwati 62db772dad Add bookshelf ISBN/paper enrichment, fix status field name collision
apps/cms/src/utils/bookshelf-covers.ts fetches book covers from Open
Library by ISBN (real image, cached into apps/site/public/covers/)
and backfills missing title/authors for papers from Semantic Scholar
by DOI/arXiv id. Wired into the sync middleware in content-sync.ts:
runs once per entry (cover_image already set means "done"), and only
on live create/update through Strapi, not during the boot-time
import (so a restart doesn't hammer external APIs).

Also renames the bookshelf `status` field to `read_status`
everywhere (schema, content/README.md, seed content, Astro zod
schema, bookshelf page, sync mapping). Strapi's content-manager API
treats a top-level `status` key as its own reserved draft/publish
parameter even with draftAndPublish disabled, so an attribute
literally named `status` silently rejected every write — caught this
while testing the enrichment hook.

Verified end-to-end: created a book by ISBN with no cover_image,
confirmed a real cover image was downloaded and cached, cover_image
was set on the entry and written to the file, and the cover/file were
both removed on delete.
2026-08-30 18:52:39 +03:00
andwati 27efeb8b26 Add Docker setup for running Strapi locally
apps/cms/Dockerfile.dev + root docker-compose.yml give a one-command
way to run the CMS in a container for testing (docker compose up
cms), with the shared content/ directory mounted so it matches the
host dev setup. apps/cms/Dockerfile is a production multi-stage build
for later Dokploy deployment. Uses node:24-bookworm-slim to match the
local Node version and get glibc prebuilt binaries for better-sqlite3
without needing a native build toolchain in the final image.

Verified: both images build, the dev container boots Strapi
successfully, admin panel and API routes are reachable, and the
mounted content/ volume resolves at the same relative path the future
sync provider will expect.
2026-08-30 18:36:31 +03:00
andwati f24701b1e7 Add TODO.md tracking remaining Astro/Strapi rebuild work 2026-08-30 18:16:55 +03:00