fix(website): ATC theme follow-ups — favicon, social cards, whitepapers - #1059
Merged
Conversation
The social card is not rendered by the site's CSS. It is a separate Satori pipeline behind Next's `ImageResponse`, and Satori cannot read woff2 or a `next/font` handle, so the card carries its own TTFs committed under `src/app/card/fonts/`. When the site was rethemed to the ATC language the card's colours were hand-copied across; its fonts were not. Share a link and the preview came back set in EB Garamond while the page it opened was Archivo Black — two products, one link. Rebuilds the bundle onto the site's own faces: Archivo Black for display, Archivo 400/600 for body, JetBrains Mono unchanged for the eyebrow and pills. EB Garamond and both Inter cuts are deleted. Two wrinkles in the build script. Archivo Black is shipped static — it has no `fvar` — so instancing is now conditional rather than unconditional; the instancer does not no-op on a font with no axes. And Archivo's variable source carries a `wdth` axis alongside `wght`, which has to be pinned like the `opsz` pin Inter needed, or variation tables survive into the output and Satori throws at request time. Archivo Black is single-weight, so the `fontWeight: 700` that sat beside every display `fontFamily` is dropped — the same removal the site's CSS made. Verified by rendering, not just by the specs: `/opengraph-image` and a blog card both return 200 image/png at 1200x630 from a built server, set in the new faces. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
These PDFs are the artifact a lead actually downloads from the site's lead form, so leaving them on the old brand meant the document and the site it came from looked like two different products. Display type moves to Archivo Black, body to Archivo, and the old #004090 brand blue to scope navy #15253E, which is the emphasis ink everywhere small text carries it: the cover eyebrow, the chapter eyebrow, the contents numbers, and inline <strong>. Archivo Black ships a single weight and no italic, so nothing pairs it with font-weight or font-style — the same synthesis smear that was swept out of the site's CSS. Aviation yellow appears once per page opener as a short fill under the heading, on the cover, the contents page, and every chapter. It is never type: at 1.84:1 on white it cannot be read. Regenerating the prose would have meant swapping a design change for a content change nobody asked for, so --rerender pours the committed chapters back through the current template without calling the model. It also drops the literal "# Chapter Title" that older runs leaked into the body directly beneath the heading that already said it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
mdToHTML had no inline-code rule and never escaped markup, so every `<chat-message-list>` in the prose reached the reader as an empty pair of backticks — the browser parsed the name as an unknown element, which renders as nothing. Twelve component names were missing from the chat paper alone. It also split paragraphs AFTER building fenced blocks, so any code sample containing a blank line was torn in half and its second half wrapped in a <p>, leaving the sample's own markup unescaped. The Angular template in the chat-debug example lost both of its element lines the same way. The source text survived in the committed HTML, so both are repaired on the way back through --rerender rather than left in a published document with words missing from it. mdToHTML is fixed too, so a fresh generation cannot reintroduce either: fenced blocks are lifted out to placeholders before the paragraph split and escaped exactly once, and inline spans are escaped. Verified by rendering the PDFs and reading them, not by inspecting the HTML. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- icon.svg becomes the yellow squircle with an ink glyph, matching the nav mark. It was still a navy field with a white plane. - --form-focus-ring was retuned to the signal yellow, which composites to 1.19:1 on white — softer than the navy it replaced, so the halo had visibly thinned. Mixed at 55% it reads again while staying the signal colour. The focused control's indicator is its navy border at 15.37:1, so this is the halo around it rather than the indicator itself. - .hero-trust was fully overridden by .hero-strip and did nothing; the class stays on the element for Hero.spec.tsx. - .hero-strip's #ffffff is now explained rather than tokenised: every candidate token is re-pointed by the enclosing signal scope. - PlaneMark's docblock claimed a navy field and an inherited colour, both false. - --color-alert is recorded as reserved with no consumer, so it does not read as an oversight. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
The lint error was real: the fence sentinel used NUL, which trips
no-control-regex. Swapped for a Private Use Area character, which cannot
appear in prose and is not a control character.
Writing a test for that then caught a defect in the previous commit. Lifting
fenced blocks out to a sentinel meant the paragraph wrapper no longer
recognised them — it checks startsWith('<pre') — so the restored block landed
inside a <p>. `<p><pre>` is invalid, so the browser auto-closes the paragraph
and leaves a stray `</p>`: a milder version of the exact artifact the rewrite
existed to remove. The wrapper now treats the sentinel as pre-formatted.
mdToHTML has now shipped three separate silent defects into published PDFs,
every one of which DELETED text rather than merely misformatting it. It had no
spec because the module built an Anthropic client at import time, which throws
under jsdom — so the client is now lazy and the helpers are exported and
pinned. Seven cases, each one a bug that actually shipped.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
…can be tested `nx test website` failed where `vitest --root apps/website` passed, and nx swallowed the output entirely — the sign of a hard crash during collection rather than a failing assertion. The cause was the spec importing generate-whitepaper.ts, which pulls in puppeteer and the Anthropic SDK at module scope. That is also the reason these functions had no spec in the first place, and therefore the reason three text-DELETING defects reached published PDFs unnoticed. A pure string function should not drag a browser-automation library into a jsdom worker, so mdToHTML and escapeHtml now live in whitepaper-markdown.ts and the generator imports them. Verified the spec genuinely runs rather than being skipped: 137 files / 1382 tests under `nx test website`, with the 7 markdown cases among them. The generator still produces byte-identical HTML. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The follow-ups deferred from #1058, plus two content bugs found while doing them. Everything here is downstream of the retheme now live on threadplane.ai.
The brand reaches the artifacts people actually take away
fvar) and pinning Archivo'swdthaxis. Verified by rendering/opengraph-imageand reading the PNG back, because the specs only assert the files exist.Two content bugs in the whitepapers, found while rethemeing them
Neither is cosmetic, and both were already shipping:
mdToHTMLhad no inline-code rule and never escaped markup. Every`<chat-message-list>`in the prose reached the reader as an empty pair of backticks — the browser parsed the name as an unknown element, which renders as nothing. The chat paper was missing twelve component names, producing sentences like "manages scroll position, virtualization hints, and message grouping logic."Paragraphs were split after fenced blocks were built, so any code sample containing a blank line was torn in half and its second half wrapped in a
<p>, leaving the sample's own markup unescaped. Thechat-debugexample lost both of its Angular element lines that way.The source text survived in the committed HTML, so both are repaired on the way back through
--rerenderrather than left in a published document with words missing.mdToHTMLis fixed too — fenced blocks are lifted to placeholders before the split and escaped exactly once — so a fresh generation cannot reintroduce either.Smaller items
--form-focus-ringhad been retuned to the signal yellow, which composites to 1.19:1 on white — softer than the navy it replaced, so the halo had visibly thinned. Mixed at 55% it reads again while staying the signal colour. (The focused control's indicator is its navy border at 15.37:1; this is the halo around it.).hero-trustwas fully overridden by.hero-stripand did nothing.PlaneMark's docblock claimed a navy field and an inherited colour — both false.--color-alertis recorded as reserved with no consumer, so it doesn't read as an oversight.Test Plan
apps/website— 1375/1375libs/design-tokens— 99/99npx nx build websiteimage/png, headline unmistakably Archivo Black, no Noto fallbackNote
npm run generate-whitepapercannot reach the model — theANTHROPIC_API_KEYin.envreports its credit balance is too low. The--rerenderpath added here re-skins the committed prose with no model calls, which is the right tool for a design change anyway. Fresh chapters need the account topped up.🤖 Generated with Claude Code