Skip to content

Redesign: article page - #39

Merged
meaningfool merged 4 commits into
redesignfrom
redesign-32-article
Nov 3, 2026
Merged

meaningfool merged 4 commits into
redesignfrom
redesign-32-article

Conversation

@meaningfool

Copy link
Copy Markdown
Owner

Implements #32 (part of #35). It builds on #36 (foundations) and has redesign merged in, with #37 (share images and favicon).

What changes

  • The article page (src/pages/articles/[slug].astro) follows the Paper design "V2 · Article — Serif text" (docs/redesign/paper/article-v2.png) and the prototype's #article view, with the column at 720px. Its <main> drops the legacy class.
    • The page is a centred min(720px, 100%) column (main.post), so Redesign: page background and topic map, prepared at build time #30's band can line up with it. This PR draws no background or pattern.
    • "← All writing" is 13px muted and links to /#writing.
    • The meta line is date · reading time · project, 12px mono at 0.04em, with the project in the accent colour. The title is mono 38px/48px at -0.05em (28px/36px on phones).
    • After the text come the "Part of the project" panel (screenshot, name, one line, link) and Previous / Next.
  • The text (src/styles/prose.css):
    • Newsreader 20px/32px (18px/29px on phones), inline code in mono 16px, links in the accent colour and underlined.
    • ## is mono 22px/30px with 48px above; ### is mono 18px/26px with 36px above.
    • Lists have muted bullets or mono numbers, hanging 22px or 28px.
    • Tables: an 11px muted mono header over an ink line, rows over a light line, numbers right-aligned in 104px mono columns (64px on phones), a highlighted row on the tint with an accent line on its left, and a 12px muted mono caption. A table that doesn't fit scrolls sideways inside its own wrapper.
    • Figures sit on the grey panel with 16px padding, with a 12px muted mono caption.
  • Headings show again (src/lib/remark-heading-levels.mjs). The page title is the only h1, and the post's headings are renumbered from h2. For example, the 11 # sections of "Agent Frameworks for the Rest of Us", hidden until now, become h2 and their subsections h3.
  • HTML shaping (src/lib/rehype-article.mjs, which runs after rehype-raw, now a direct dependency):
    • Figures and their captions.
    • YouTube embeds load from youtube-nocookie.com with loading="lazy", in a 16:9 figure. The three in "Thoughts on Human-AI Collaboration" answer 200 there.
    • Tables: number columns are found from their cells, and the highlighted row and the caption follow the conventions below.
  • Meta description: the description field, or else an excerpt of the first paragraph (src/lib/excerpt.ts), or else the title. The JSON-LD description uses it too.
  • Projects (src/data/projects.ts): the shared module for Redesign: home page #31 and Redesign: share images and favicon #34, newest first.
    • Each project has slug, name, shortName, type, date (YYYY-MM), description, link, linkText, screenshot and articles.
    • The screenshots are the prototype's, copied to src/assets/projects/.
    • The links are https://voice-todos.meaningfool.net/, https://agent-frameworks-report.meaningfool.net/ and https://lineage.meaningfool.net/. I found them by checking those hosts.
    • Which article belongs to which project comes from the prototype (maps.js) and is kept in this data file, by article id. Nothing was pushed to meaningfool-writing.
      • Voice Todos: edit-collections-generative-ai, structured-extraction, thoughts-on-human-ai-collaboration
      • Agent SDKs for the Rest of Us: agent-frameworks-for-the-rest-of-us
      • Data Lineage: antigravity_is_onto_something
    • The build warns if one of these ids doesn't exist.
  • Merge with Redesign: share images and favicon #37:
    • The page passes Redesign: share images and favicon #34's share to the Layout and uses it as the JSON-LD image.
    • It takes its date and reading time from Redesign: share images and favicon #34's articleMeta(), so the meta line and the share image print the same values. The reading time is src/lib/reading-time.mjs, 235 words a minute rounded up, which gives the prototype's minutes for all 18 articles.
    • projects keeps the slug and name that the share images count.
  • CSP: the report-only policy in public/_headers already allows frame-src https://www.youtube-nocookie.com, so nothing needed adding. www.youtube.com stays for embeds this doesn't rewrite.

Content conventions (documented in this repo's AGENTS.md)

  • In a table, a row whose cells are all bold is highlighted, and its bold is drawn at normal weight. "Giving Agents the Ability to Point at Things" already has one such row.
  • A paragraph starting with Table: after a table, past a blank line, becomes its caption.
  • An image alone in its paragraph is captioned with its title, or with its alt text when that has a space. An alt text such as cost-of-rework is a file name, so it gets no caption.

Proposed for meaningfool-writing (not done: a push there deploys the live site)

  • In 2026-05-27-structured-extraction.md, the design's highlighted Mistral row and its caption need the Mistral row in bold and a Table: … line after the table. The design also shows 6 of the 17 rows.
  • Its AGENTS.md still says that # headings other than the title are hidden. It could describe the heading levels and the conventions above.

Choices to check

  • Footer: it keeps Redesign foundations: fonts, colours, header, footer and 404 #36's frame-wide footer, as in the Paper export. The prototype has it inside the 720px column.
  • "← All writing" goes to /#writing, which works once Redesign: home page #31 gives the home's Writing section id="writing". Today's home has no such anchor, so the link lands at the top of the home.
  • Not in the design, so these are my picks:
    • Code blocks use Shiki's github-light in a 1px line frame, instead of the dark block.
    • Quotes sit on the tint with a 2px accent line.
    • Paragraphs are 20px apart, and #### is mono 16px/24px.
    • Videos and embeds sit on the same grey panel as images.
    • Images keep their own proportions; the prototype cropped its sample to 16:10.
  • Activity logs use this page too:
    • Previous and Next link articles to articles and logs to logs.
    • Logs show no project.
    • A log without a usable paragraph keeps its title as its description.
  • Project links: "Try Voice Todos ↗", "Read the report ↗" and "Try Data Lineage ↗". The prototype shows only the first. The meta line uses the full project name.
  • Bold: Newsreader is loaded at 400 only, so bold is drawn by the browser, as in the prototype.

Validation

Head commit c8250b4bbf5014178f944fb2d78006e14497d2f9. It merges origin/redesign at 3df7e3843cdd06cf5d6c73d7b32e6443c3007262 (#37) into the work started on 4cf01a4. Node 24.22.1, Bun 1.4.4, content at bf783ba (git submodule update --init --remote).

  • bun install --frozen-lockfile, then bun run build: passes, 62 pages.
  • bun run test:documents: 10 tests, 10 passed.
  • Pages outside the issue. I compared this build with a build of 3df7e38.
    • Only the 58 post pages (18 articles and 40 activity logs) change, plus the build timestamp in llms*.txt.
    • The home, About, 404, /documents/, rss.xml, the sitemap, _redirects, robots.txt, _headers and the share images are byte-identical.
  • Prototype comparison. I took Playwright/Chromium screenshots and measured element boxes at 1440px and 375px.
    • For the prototype, the site's Newsreader was put in place of Google Fonts', and Menlo falls back to DejaVu Sans Mono. To compare like with like, I also built once with the prototype's sample text in place of the article; that file was restored afterwards.
    • At 1440px:
      • The column runs from x=360 to 1080, as in the prototype.
      • Back link, meta line, title, table, figure, project panel (720×150, screenshot 176×110 at x=380) and Previous/Next (89px tall) have the prototype's sizes.
      • The vertical positions match within 2–17px: 8px is the prototype's default body margin, and the rest comes from lines that hold inline code, about 2px taller each in the prototype.
      • Table text starts at x=374 in both, and the number columns are 104px from x=756.
      • The fonts, sizes, line heights and tracking that the browser reports match the issue.
    • At 375px: the same layout, with the 24px gutter from Redesign foundations: fonts, colours, header, footer and 404 #36 (the prototype has 32px). The project panel stacks, number columns are 64px and the title is 28px/36px.
    • The footer differs, as noted above.
  • No horizontal scroll. All 58 post pages are checked at 375px and 1440px: none is wider than the viewport. Before this change the 2025-09-09 activity log was 418px wide at 375px.
  • Edge cases run through the Markdown pipeline:
    • heading renumbering;
    • YouTube embeds in a <div>, in a paragraph, in a list and in a figure, protocol-relative, a site-relative /embed/… that is left alone, and other hosts;
    • table captions (with and without the blank line), highlighted rows, number columns, image captions from title and alt, block-level videos and numbered lists not starting at 1.

Review gate

There were 5 review passes over the whole change. These were fixed:

  • Excerpt:
    • only the text's own paragraphs count, not those in lists, quotes, tables or figures;
    • line breaks between sentences become full stops;
    • short labels such as "Readings:" are skipped;
    • cuts at abbreviations are avoided;
    • tags with > in attributes are handled;
    • invalid character references no longer throw.
  • Embeds:
    • a relative /embed/… iframe is no longer taken for YouTube;
    • an embed in a paragraph keeps its sizes and is held to the column;
    • no figure is created inside a link or a figure;
    • the #fragment is kept.
  • HTML shaping:
    • a video on its own block becomes a figure;
    • embeds inside table cells are shaped;
    • an empty Table: caption is ignored;
    • a list's own inline style is kept;
    • an inline image in a list no longer widens the page.
  • Wording: the caption convention says a blank line is needed, and a misleading comment was corrected.

Left as they are, with the reasons:

  • the /#writing anchor, which waits for Redesign: home page #31;
  • RSS still sends only the description field, which is outside the issue;
  • the reading time counts the Markdown's words, so that it matches the prototype and the share images;
  • a wrong article id in projects.ts gives a warning rather than an error, so that renaming an article doesn't block a deploy;
  • rehype-raw runs twice, which only costs build time.

Generated by Claude Code

The article page follows the Paper design "V2 · Article — Serif text" with a
720px column: the back link to the home's Writing section, the meta line
(date, reading time, project), the mono title, the text in Newsreader, then
the "Part of the project" panel and Previous and Next.

- prose.css styles the Markdown: headings, lists with muted bullets or mono
  numbers, inline code, code blocks, quotes, figures on a grey panel, and
  tables with numbers in 104px mono columns, a highlighted row and a caption.
- rehype-article.mjs shapes the HTML for it: figures and their captions,
  YouTube embeds moved to youtube-nocookie.com and loaded lazily, tables
  (number columns, the row whose cells are all bold, a "Table:" caption).
- remark-heading-levels.mjs shows the headings again, renumbered from h2.
- src/data/projects.ts holds the three projects, their screenshots and which
  articles belong to each, for this page, the home and the share images.
- The meta description falls back to an excerpt of the first paragraph.

Implements #32.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
…2-article

Keep both sides: the article page passes #34's share image to the Layout and
uses it in its JSON-LD, and takes its date and reading time from #34's
articleMeta(), so the meta line and the share image print the same ones
(235 words a minute). src/data/projects.ts keeps the full project data, with
the slug and name that the share images count.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
@meaningfool meaningfool mentioned this pull request Nov 3, 2026
@github-actions

github-actions Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

Preview: https://pr-39-meaningfool.josselin-perrus.workers.dev

Built from 94fffd2 with the latest content. The link stays the same and shows the latest push. Search engines are asked not to index it.

"Agent Frameworks for the Rest of Us" opens with a `##` before its first
`#` section, which the renumbering made an h3 straight under the page
title. Headings now go at most one level deeper than the heading before
them, the title included, so it becomes an h2 like the parts after it.
No other post changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
Astro keeps each post's rendered HTML in node_modules/.astro, which the
deploy workflow restores from its cache, and renders a post again only
when the post or the config it compares changes. Plugin functions drop
out of that comparison, so the preview of acfbd34 still served the
previous heading levels. A hash of the plugins' sources and bun.lock now
goes into the config, as rehypeArticle's unused options. The built site
is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2

Copy link
Copy Markdown
Owner Author

Review checkpoint: accepted at 94fffd29d0e66475301cb1c2471bffd612222ba5

This was an independent review of this PR against #32, with #35, AGENTS.md and docs/redesign/. It took 3 passes, and 2 fixes were pushed.

Setup

  • Node 24.22.1, Bun 1.4.4, content at bf783ba.
  • bun install --frozen-lockfile, bun run build (62 pages) and bun run test:documents (10/10) pass.
  • The Deploy build check passed on 94fffd2.

What I checked

  • Each item of Redesign: article page #32, in the build and in Chromium:

    • the 720px column (x=360–1080 at 1440px) and "← All writing" to /#writing;
    • the meta line, the title, the text at 20/32 and 18/29, inline code, links;
    • ##/### sizes and spacing, lists;
    • tables: 104px number columns (64px on phones), and the highlighted row on "Giving Agents the Ability to Point at Things";
    • figures, the project panel, Previous/Next;
    • the description fallback;
    • the 3 YouTube embeds, on youtube-nocookie.com, lazy, all answering 200.

    No background is drawn.

  • Prototype #article, at 1440px and 375px:

    • The back link, meta line, title and start of the text are at the same offsets from the column top (0px apart).
    • The gaps between blocks are the same: 48, 12, 10, 20, 36, 56, 24, 36, 36 and 10, then 72 before the panel. The panel is 720×150 and Previous/Next is 89px tall. The browser reports the same fonts, sizes, line heights and tracking.
    • The differences are the ones already listed: content, the footer, the gutter.
  • Outside the scope: I compared this build with a build of origin/redesign (3df7e38).

    • Only the 58 post pages change, plus the timestamps in llms*.txt.
    • The home, About, 404, /documents/, RSS, the sitemap, _redirects, _headers and the share images are byte-identical.
  • All 58 post pages at 375px and 1440px: none scrolls sideways, and nothing sticks out of the column. I also looked at the activity logs 2025-09-09 and 2025-11-25.

  • The preview at 94fffd2: all 58 post pages, the home, About and 404 are byte-identical to the local build.

  • Rules:

    • Internal links end with a slash.
    • The CSP already allows youtube-nocookie.com.
    • No file is over 25 MiB.
    • No secrets or personal data: the screenshots are the prototype's own files.
    • Nothing was pushed to meaningfool-writing.

Fixed in review

  • acfbd34: a heading now goes at most one level below the heading before it.
    • "Agent Frameworks for the Rest of Us" opens with a ## before its first # part. That made "Agent Frameworks Landscape" an h3 straight under the h1; it is now an h2.
    • No other page changes.
  • 94fffd2: the posts are rendered again when the Markdown plugins change.
    • Astro keeps each post's rendered HTML in node_modules/.astro, which withastro/action restores from its cache. It renders a post again only when the post or the serialisable config changes, and plugin functions aren't part of that.
    • So the preview of acfbd34 still had the h3: wrangler uploaded only llms*.txt.
    • astro.config.mjs now passes a hash of the three plugins and bun.lock to rehypeArticle. A plugin edit now clears the store, an unchanged build keeps it, and the output is unchanged.

Left as is (minor)

  • JsonLd.astro writes JSON.stringify into a <script> without escaping <. The excerpt now puts post text there, so a first paragraph that contains </script> would break the page. No post does today.
  • An image captioned from its alt text gives screen readers the same text twice.

Generated by Claude Code

@meaningfool
meaningfool marked this pull request as ready for review November 3, 2026 19:31
@meaningfool
meaningfool merged commit 572200e into redesign Nov 3, 2026
1 check passed
@meaningfool
meaningfool deleted the redesign-32-article branch November 5, 2026 10:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants