Skip to content

Redesign: About page - #41

Merged
meaningfool merged 3 commits into
redesignfrom
redesign-33-about
Nov 3, 2026
Merged

meaningfool merged 3 commits into
redesignfrom
redesign-33-about

Conversation

@meaningfool

@meaningfool meaningfool commented Nov 3, 2026 •

Copy link
Copy Markdown
Owner

Implements #33 (part of #35). It builds on #36 (foundations), #37 (share images), #39 (article page) and #38 (background and topic map), and runs alongside #31 (home).

What changes

  • About (src/pages/about.astro) follows the prototype's #about view. Its <main> drops the legacy class.
    • Intro: the shared Intro, with "About", the title "Customer success, / Product, / AI agents." (the full stop in the accent colour) and the issue's text. The map's dots link to the three parts: links={{ 'customer-success': '#customer-success', product: '#product', 'ai-agents': '#ai-agents' }}.
    • The three parts sit on the intro's two columns:
      • The heading is under the intro text: the orange dot, the name at 18px, and the map's label in 10px grey capitals. It stays in view at 32px from the top while its part is read.
      • The text is under the map, in Newsreader 20px/32px (18px/29px below 900px), with paragraphs 20px apart.
      • Below 1120px the parts are one column of up to 720px, and the heading no longer sticks.
      • The parts' styles are the prototype's own (.chapter), written in the page. prose.css styles links differently (accent text instead of an accent underline), so I didn't reuse it.
    • Copy: the issue's text, word for word (checked with a script against the issue).
    • "GitHub" links to the boundary model Skills: https://github.com/meaningfool/skills/tree/main/skills/boundary-model. That is the owner's public meaningfool/skills repository; I cloned it and checked that skills/boundary-model/ (with its README) is on main.
    • Kept: the Person JSON-LD (unchanged), the title and description, and the shared Home/About share image (/share.png).
  • Going from Home to About moves the map without drawing it again. This uses Astro's ClientRouter, limited to Home and About. It is built into the shared pieces, so Home gets it with no change to index.astro:
    • src/lib/intro-pages.ts lists / and /about/. Layout renders the new IntroRouter.astro in the <head> of those two pages only.
    • Between Home and About, a link swaps the page in place, at once: no cross-fade (Astro's transition:animate="none" for the root), and a plain swap where view transitions aren't supported (fallback="swap").
    • TopicMap carries its canvas over to the next page's <topic-map>. It records what each canvas has drawn by canvas (a WeakMap), so the next page's map sees the canvas as drawn and only draws it again if its size changed by more than a tenth.
    • Background keeps its <page-background> element, with its drawing and listeners, and its hole moves to the next page's map. This applies only to Home and About; articles have their own mask.
    • Links to any other page load it in full, as before. A guard on astro:before-preparation sends the browser there directly, so the page isn't fetched twice. Articles, activity logs, /404.html, /documents/ and /map-preview/ have no router.
    • No prefetching (prefetch: false in astro.config.mjs). With the router, Astro would otherwise prefetch every link the pointer goes over.
  • Layout and Background only gain things: Background gets an optional persist prop, and Intro and TopicMap's API (links, topicmap:pick, data-picked) are unchanged. legacy.css stays.

For #31: what the home can rely on

  • Home already has the router: / is in src/lib/intro-pages.ts. Putting Intro in the page, inside a Layout without textColumn, is all it takes for the map to stay drawn between Home and About.
  • Only the canvas is kept. Home's <topic-map> is always its own, with button dots, aria-pressed, no data-picked on arrival, and no listeners from About. About's map has link dots. So the issue in Redesign: page background and topic map, drawn from prepared images #38, where a kept element keeps the markup of the page it came from, doesn't arise.
  • A page's script runs once, the first time the page is shown, and keeps running afterwards. This is how the ClientRouter works. In practice:
    • Home's document.addEventListener('topicmap:pick', …) also hears About's dots after a visit to About. Return early when not on Home, for example if (!document.getElementById('writing')) return;.
    • About adds no pick listener: its dots are plain links to its parts.
    • Each visit to Home brings fresh HTML. Keep the picked topic in the DOM (data-picked, the hidden rows) rather than in a module variable, or reset it on astro:page-load.
    • Elements your script found at load are gone after a swap. Find them again from the event, or on astro:page-load.
  • About to Home and back: the router brings Home back at the top, or at its saved scroll on Back. "About me →" and the header links go through the router. Links to articles load in full.

Choices to check

  • The first figure of the Product part, "€1K / year / customer", is to be confirmed by the owner before the final merge (Redesign: build the approved design on the redesign branch #35). It is as written in the issue.
  • Copy, word for word from the issue: "a now-solution beats everyday a beautiful solution". "Every day" would be the usual spelling; I left it for the owner to decide.
  • Map dots on About are links, as Redesign: page background and topic map, drawn from prepared images #38's links intends. As in the prototype, they scroll smoothly to the part, 24px from the top. Unlike the prototype, the address gets the part's #fragment and Back returns to where you were. The smooth scroll is CSS scroll-behavior: smooth, set only while About is shown and only without reduced motion, so the native fragment move (focus, screen readers) is kept. It also makes the skip link and a direct /about/#product scroll smoothly.
  • Footer: the frame-wide footer from Redesign foundations: fonts, colours, header, footer and 404 #36 ends the page, as on every page. The prototype's About has none.
  • Below 1120px the map is under the intro text, so its place depends on each page's text. It is still carried over, not drawn again, but it moves.
  • Today's Home is still the legacy page with no map. Going between it and About already swaps without a full load and keeps the background. The page is pixel-identical whether you reach it that way or load it directly. The map is kept once Redesign: home page #31 puts the intro on Home.
  • Persistence attribute: the canvas and the background carry data-astro-transition-persist, the attribute transition:persist writes, set by hand. The directive would also add Astro's view-transition CSS (keyframes and a reduced-motion rule) to every page with the background, /404.html and /documents/ included. If an Astro upgrade ever renames the attribute, the map and background are simply drawn again on each move.
  • One inert CSS rule on other pages: Astro bundles a component's styles wherever it is imported. Every Layout page, including articles and logs, now has ClientRouter's .astro-route-announcer rule (about 170 bytes) in its CSS. It only applies to an element the router creates, and those pages render pixel-identically.
  • Analytics: Home↔About moves are pushState navigations. Cloudflare's docs say Web Analytics "automatically tracks user interactions on Single Page Applications" by patching pushState, automatic setup included, so they are still counted. The router doesn't run the injected beacon script a second time, since its src is the same. I couldn't check this end to end locally, because the beacon is only added at Cloudflare.
  • Map label: About's map keeps the prototype's accessible name, "Map of the writing: Customer success, Product and AI agents".

Validation

Head commit 1f36b5ea7e5746d0e16bfe77f1bd158574352ab2, on base 78b78fdcbeda08341f25c4c84560d04d8aa5d36f (origin/redesign, with #38). Node 24.22.1, Bun 1.4.4, content submodule at bf783ba (git submodule update --init --remote; the pointer is not changed).

  • Build and tests:
    • bun install, then bun run build from an empty dist/: passes, 63 pages.
    • bun run test:documents: 10 tests, 10 passed.
    • astro check (TypeScript 6, in a scratch copy): 0 errors, 0 warnings, 0 hints.
  • Prototype comparison (docs/redesign/prototype/index.html#about):
    • Method: Playwright and Chromium, screenshots and the boxes of 30 elements. The prototype was given a local copy of @paper-design/shaders@0.0.81, and the site's Newsreader in place of Google Fonts'.
    • 1440px: all 30 boxes are the prototype's, 8px higher (the prototype keeps the body's 8px margin). That covers the label, title, text, map (636 × 454.3), the three parts, their headings and labels, every paragraph and the GitHub link. Fonts, sizes, line heights, tracking and capitals match. The headings stick at 32px.
    • 1000px: the same boxes, 8px further left, from the 24px gutter of Redesign foundations: fonts, colours, header, footer and 404 #36. The map is 560 × 400 under the text, and the parts' text is 720px wide.
    • 375px: the same layout with the 24px gutter. The text is 16px wider, so one paragraph wraps to one line fewer, and the map is 327 × 234.
    • No sideways scroll on About at 13 widths from 320px to 2560px. No console errors, and no request to another host.
  • The move from Home to About (Playwright, at 1440px and 375px, on a scratch copy whose Home uses Intro the way Redesign: home page #31 will; not committed): 43 and 41 checks passed. In short:
    • Home → About doesn't reload the page. It fetches /about/ once.
    • The same map canvas and background element arrive. Each is filled once, so nothing is drawn again. At 1440px the map is in the same box.
    • About's dots are links with no pick. Home's are buttons again on the way back, and Home's script ran once.
    • A dot on About scrolls smoothly to its part. Back and Forward go through the router. A dot on Home picks with aria-pressed, and the pick is gone after visiting About.
    • Resizing after the move draws again once. Home → article is one plain document load with no prior fetch, and the article has no router and the column mask.
    • Loading About first, then going to Home, carries About's canvas.
    • With the map image held back until after two moves, the map is drawn once, on the final page.
  • The real build, whose Home is still legacy (17 checks at each width):
    • Home ↔ About keeps the background, and About draws its map on arrival.
    • Legacy Home through the router matches a direct load pixel for pixel, and About through the router matches a direct load of About.
    • The /map-preview/ → About case found in review is a full load, with no pick left on About.
    • Scroll on Back is restored as before: Home 600 → 600 after an article, About 500 → 500 after Home.
    • The skip link works, and so do keyboard Tab and Enter on the dots. With reduced motion the jump is instant.
  • Pages outside the issue (base build against head build):
    • Byte-identical: /404.html, /documents/, rss.xml, the sitemap, _redirects, _headers, robots.txt and the share images. llms*.txt differ only in their timestamp.
    • The 58 article and log pages differ only by the inert .astro-route-announcer rule.
    • /map-preview/ gains the same rule, TopicMap's new script and the canvas attribute.
    • The legacy Home gains the router and the background's persist attribute.
    • Full-page screenshots of /, three articles, a daily log, an unknown URL, /documents/ and /map-preview/ were compared at 1440px and 375px, base against head.
      • A first run (14 pairs, without agent-frameworks-for-the-rest-of-us) matched pixel for pixel.
      • In a second run of all 16, two article pages differed: structured-extraction, and thoughts-on-human-ai-collaboration, which has YouTube embeds.
      • Rerun with outside requests blocked, thoughts-on-human-ai-collaboration matched at both widths.
      • structured-extraction differed once more, but it also differs between two loads of the base build itself. Base against head then matched 3 times out of 3.

Review gate

4 passes over the whole change:

  1. I reviewed it myself and checked the edge cases above. Nothing to fix.
  2. An independent review. Fixed: the router was on every page without the text column, /map-preview/ included. Going from there to About kept map-preview's pick listener running on About. The pages are now listed once, in src/lib/intro-pages.ts, which Layout and IntroRouter both read. The other points it raised are explained under "Choices to check".
  3. A second independent review. Nothing at P1 or P2. I corrected a stale comment in TopicMap. Left as they are: the inert announcer rule, the background's extra connect and disconnect calls during a swap (a few microseconds), and the copy above.
  4. A full rerun of every check above on the head commit. Nothing to fix.

🤖 Generated with Claude Code

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
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
@github-actions

github-actions Bot commented Nov 3, 2026

Copy link
Copy Markdown

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

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

Copy link
Copy Markdown
Owner Author

Independent review checkpoint: accepted at 1f36b5ea7e5746d0e16bfe77f1bd158574352ab2. One pass. Nothing found at P1 or P2, so nothing was pushed.

Setup: Node 24.22.1, Bun 1.4.4, content submodule at bf783ba. bun run build passes (63 pages, no warnings) and bun run test:documents passes 10 of 10. The Deploy build check passed on this head.

Note on the base: redesign has moved to 319deac (#40 merged). Merging this PR into it gives tree 0869662. That is the same tree as the throwaway merge with redesign-31-home (cd5b9e8) tested below, and it has no conflicts.

What I checked

Issue #33 requirements

  • Copy: the label, title (accent full stop), intro text and all three parts match the issue word for word: ASCII apostrophes, €, and compound / boundary model in italics.
  • Kept: the Person JSON-LD is byte-identical to the base. The title, description and /share.png are unchanged.
  • "GitHub" link: it goes to meaningfool/skills/tree/main/skills/boundary-model. I cloned that public repo, and skills/boundary-model/ with its README is on main.
  • Owner's call: the first figure (€1K) is flagged in the PR and left as written, as is "everyday".

Against the prototype (docs/redesign/prototype#about, shaders@0.0.81 and Google's Newsreader fetched for real; Playwright and Chromium)

  • 1440px: all 30 boxes match the prototype, 8px higher because of the prototype's body margin. That covers the label, title, text, map (636×454.3), the three parts, their headings and labels, every paragraph and the GitHub link. Font size, line height, tracking, case and colour match. The only difference is the order of the mono font stack, which comes from Redesign: foundations (fonts, colours, header, footer, 404) #29.
  • 375px: the same layout on the 24px gutter from Redesign foundations: fonts, colours, header, footer and 404 #36. The map is 327×234 and one paragraph wraps to one line fewer.
  • Other widths: 1000, 1119 and 1120px are also checked. Below 1120px the parts are one 720px column, and the 18/29 text size switches at 900px. There is no sideways scroll at any width from 320px to 2560px.
  • Sticky headings: at 1120px and wider they hold at 32px in each part. Below that they don't stick.
  • On Home and About the label, title and map are in the same box at 1440px and 1200px.

The move, on this branch alone (legacy Home) and merged with redesign-31-home, at 1440px and 375px: 101 + 20 + 53 scripted checks. The only failures were the expected dot-scroll case explained below.

  • Home → About: no page load. /about/ is fetched once. The same canvas and page-background arrive, and each has been filled only once. At 1440px the map is in the same box. About's <topic-map> is its own, with link dots and no data-picked. The nav's current link, the title and the background's hole are all updated.
  • About's dots: each one sets #fragment and scrolls its part to 24px from the top, by mouse and by Enter. One exception: Product and AI Agents at 1440×900, and AI Agents at 375×900, can't reach 24px because the page ends first. The prototype does the same.
  • Back and Forward: these go through the router with the same canvas, not redrawn. Home comes back with no pick, the full list and aria-pressed=false.
  • Home's filter after every move: each click raises exactly one topicmap:pick event, so no listeners stack up. Show all clears the pick, a second click on a dot unpicks, and loading About first and then going Home works too.
  • Home → article → "← All writing" → Home: the article is one plain document load, with no router and the column mask. Home loads fresh, scrolled to #writing, and its filter works. About → Home → Back keeps the scroll position.
  • Slow map image (held until after two moves): the map is drawn once, on the final page. Resizing from 1440px to 1000px redraws it once.
  • Router against direct load: Home and About reached through the router are pixel-identical to a direct load, on this branch and in the merge.

Outside the scope

  • Base build against head build: /404.html, /documents/, portfolio-entry.js, _headers, _redirects, rss.xml and the sitemap are byte-identical. The article and log pages gain only the inert .astro-route-announcer rule.
  • Screenshots: /, three articles, a daily log, an unknown URL, /documents/ and /map-preview/ match pixel for pixel at 1440px and 375px. I did this against 78b78fd and, for the merge, against 319deac. structured-extraction differed once because of a lazy-loaded image that hadn't loaded yet; it matched on reruns.
  • Pages without the router: the 404, /documents/ and the logs have no router and nothing persisted.
  • CSP: I enforced the _headers policy instead of report-only and went Home → About → dot → Home → article. There were no violations. The router fetches same-origin, and its scripts are 'self' files.
  • Repo rules: nothing in the diff is a secret or personal data, and no file is over 25 MiB.

Notes, not blocking: the 170-byte .astro-route-announcer rule on every page that uses Layout, and the footer on About, which the prototype's About doesn't have (both are already in the PR).


Generated by Claude Code

@meaningfool
meaningfool marked this pull request as ready for review November 3, 2026 21:13
@meaningfool
meaningfool merged commit 118b781 into redesign Nov 3, 2026
1 check passed
@meaningfool
meaningfool deleted the redesign-33-about 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