Skip to content

Redesign: ship the new site - #43

Merged
meaningfool merged 28 commits into
mainfrom
redesign
Nov 4, 2026
Merged

meaningfool merged 28 commits into
mainfrom
redesign

Conversation

@meaningfool

Copy link
Copy Markdown
Owner

Merges the redesign branch into main. This ships the whole new site at once, as planned in #35. It stays a draft until the owner has approved the full preview below.

Merged into redesign

Pull request Issue Preview
#36 Foundations: fonts, colours, header, footer, 404 #29 https://pr-36-meaningfool.josselin-perrus.workers.dev
#37 Share images and favicon #34 https://pr-37-meaningfool.josselin-perrus.workers.dev
#39 Article page #32 https://pr-39-meaningfool.josselin-perrus.workers.dev
#38 Page background and topic map #30 https://pr-38-meaningfool.josselin-perrus.workers.dev
#40 Home page #31 https://pr-40-meaningfool.josselin-perrus.workers.dev
#41 About page #33 https://pr-41-meaningfool.josselin-perrus.workers.dev
#42 Remove the unused legacy stylesheet (cleanup, rendered site unchanged) follows #33 https://pr-42-meaningfool.josselin-perrus.workers.dev

Each pull request was built by one agent and checked by a separate reviewer. It was merged only after the review was accepted at its head commit and the Deploy workflow's build check passed on that head. The pull requests list the points that still need the owner's decision.

main (3bce767) is already contained in redesign (b5c7f46), so this merge brings no conflicts.

Tracks #35.

Before merging redesign into main (from #35)


Generated by Claude Code

meaningfool and others added 28 commits November 3, 2026 17:31
The prototype from #8 lived only in a temporary folder. It now sits in
docs/redesign/: the page source, the topic map data, the images, a build
script that makes a single index.html, and the scripts that generated the map.

Refs #35

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Cloud sessions can't open the Paper file, so docs/redesign/paper/ now has
the exported images and their exact values. The Home and About share image
gets its text updated to the new intro and navigation.

Refs #34, #32

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Self-host subsets of DejaVu Sans Mono and Newsreader (regular and italic,
optical size kept) in src/fonts/, made by scripts/subset-fonts.py, and stop
loading Space Mono, Roboto Mono and Poppins from Google Fonts. The colours
and fonts are custom properties in src/styles/tokens.css, and the base
styles, without the weight-300 body text, are in global.css.

Every page is built in a new Frame component: up to 1240px wide with 24px
side padding, the new header (wordmark, Home and About, the current page
underlined in the accent colour) and the new footer (wordmark, About,
LinkedIn, GitHub, X). The 404 page and the not-found view of /documents/
use it too and look the same. The pages not yet redesigned keep their
content styles in legacy.css, under a legacy class, until #31, #32 and #33
rebuild them. The text of articles and About is now in Newsreader.

Implements #29.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
Each article gets its own 1200x630 share image (its title, date and
reading time) at /articles/<slug>/share.png, and Home and About share
/share.png, with the label "Projects · Writing", the home intro and
the article and project counts. Activity logs use the site's image.
They replace og-default.jpg as og:image and twitter:image, now with
their size and alt text.

The favicon is the paper tile: favicon.svg (the 32px tile), a
favicon.ico at 16px and 32px and a 180px apple-touch-icon. They
replace Astro's default logo on every page, the 404 and /documents/
included.

Everything is drawn from the site's DejaVu Sans Mono subset, read with
fontkitten and turned into SVG paths laid out as the browser lays out
text, then rasterised with sharp. The values are those of
docs/redesign/paper/README.md. src/data/projects.ts is a minimal
project list for the count, until #32's replaces it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
At 230 words a minute, "Agent Frameworks for the Rest of Us" came out at
40 minutes, where the approved prototype shows 39. Any rate from 231 to
236 gives the prototype's reading time for all 18 articles; only that
article's share image and alt text change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
The paper texture, the corner pattern and the "Best of three" topic map now
look as in the prototype without a shader library or WebGL.
scripts/make-background.py computes them ahead of time, following the
prototype's recipe and Paper Shaders' halftone shader, and writes three small
images to src/assets/background/: a 140px paper tile, the corner pattern's
ink on a polar grid, and the map's ink. The browser only lays the dots out and
draws them once on a canvas, and on resize stretches what is drawn until
resizing stops.

- Background.astro, behind every page and the 404: the paper, the corner
  pattern at 6%, the hole around the map and, on articles, the band behind
  the centred 720px column.
- TopicMap.astro: the map, with its orange dots as buttons or links that send
  a topicmap:pick event, and a data-picked state.
- Intro.astro: the two-column intro of Home and About, with the map.
- map-preview.astro: a temporary page to review the intro and the map, until
  the home (#31) uses them.
- Scripts are kept out of the HTML, as the Content-Security-Policy only allows
  the site's own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
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
Brings in the share images and favicon (#37). Layout keeps their share prop
and adds textColumn and noindex next to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
"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
Implements #32, part of #35.
On a 1x canvas the dots smaller than a pixel lose some of their ink, and
the map came out 8% lighter than the prototype's. The shader renders at
twice the CSS pixels or more, so draw the map the same way: it is now as
dark at 1x and 1.5x as at 2x.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
Implements #31, part of #35.

- The intro: the shared Intro block with the home's text (HOME_INTRO), the
  "About me" button and the profiles, beside the topic map.
- Projects: a tile per project from src/data/projects.ts, newest first.
- Writing: the articles only, newest first, with their date, project and
  reading time; the section is #writing, where "All writing" goes. The
  activity logs keep their pages but leave the home.
- Picking a dot on the map shows only the articles about its topic. An
  article's topics come from a `topics` frontmatter field, or else from
  src/data/topics.ts, which holds the prototype's reading of the 18
  articles. The script also works when a ClientRouter swaps pages.
- The page has its own title and meta description.
- The temporary /map-preview/ page (#30) is gone, with its sitemap filter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
- Clear the map's pick when the ClientRouter leaves the home, so a map kept
  for the next page arrives without it.
- Guard the Show all listener against clicks on non-elements, and pass the
  Writing list to show() instead of looking it up twice.
- Take the unfiltered count text from the page, built with share.ts's
  plural(), rather than repeating it in the script.
- Warn only about articles that have no topics at all, not about an
  explicit `topics: []`, and fail the build if topic-map.json's topics stop
  matching TOPICS.
- Use readingMinutes() and the projects' own order directly.
- Describe the home and its topics in AGENTS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
About gets the home's intro (label, title, text and the topic map at the
same place), then one part per island of the map: the heading under the
intro text, staying in view while its part is read, and the text under
the map in Newsreader 20px/32px (18px/29px on phones). Below 1120px the
parts are one column of up to 720px. The map's dots link to the parts.
The Person JSON-LD is kept, and the page drops the legacy class.

Going from Home to About moves the map without drawing it again: Layout
now renders Astro's ClientRouter on the pages with the intro map
(introMap, on by default without the text column), held to Home and
About. TopicMap carries its canvas over to the next page's map and
Background keeps its element; links to any other page load in full, as
before, and nothing is prefetched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
- Rewrite the Writing count only when it changes: it is a live region, so
  resetting it on arrival made screen readers read it again.
- After "Show all", move the keyboard's place to the Writing heading rather
  than to the live region, which it would read twice.
- Mark the pick on the map that was clicked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
- After "Show all", always move to the Writing heading: Safari doesn't focus
  a clicked button, and the screen reader's place went with the button.
- Hide the "—" of rows without a project from screen readers.
- Underline only a project's name on hover, not the space and arrow.
- Warn when src/data/topics.ts names an article that doesn't exist, as
  projects.ts does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
The router was on every page without the text column, so the temporary
/map-preview/ had it too: going from there to About kept map-preview's
pick listener running on About. src/lib/intro-pages.ts now lists Home
and About, and Layout and IntroRouter both read it, so the pages that
get the router and the pages it goes to can't drift apart. Layout's
introMap prop is gone.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
At 30% or more, every article has at least one topic, so an empty list is a
mistake like a missing one. Say in the script what a page restored from the
back-forward cache does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
Implements #31, part of #35.
Implements #33, part of #35.
The home (#31), the article page (#32) and About (#33) have been rebuilt,
so no page carries the legacy class any more. src/styles/legacy.css, kept
for them since #29, only still set the root font size to 18px, which
nothing uses: no other rule is in rem, and body sets its own 13px, so no
text inherits it. Remove the file, its import in Layout and its mention in
AGENTS.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013MdjUerTCBDeF5DG9puDd2
Redesign: remove the unused legacy stylesheet
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown

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

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

@meaningfool
meaningfool marked this pull request as ready for review November 4, 2026 08:19
@meaningfool
meaningfool merged commit e8c17cc into main Nov 4, 2026
1 check passed
@meaningfool
meaningfool deleted the redesign 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