Let the .mono class reach the text nodes it wraps - #186
Conversation
A house `text{font-family:…}` type selector matches every text node
directly, so it outranks the monospace face *inherited* from an
ancestor group carrying `class="mono"`. The face was declared,
inherited in principle, and never applied: code blocks, AGENTS.md
samples and log lines all rendered in the sans-serif body face.
(`font-size` on the same class did land, because no competing
`text{font-size}` rule exists — which is why the blocks looked
deliberately sized but wrongly faced.)
Add one rule per asset, `.mono text{font-family:inherit}`, which is
specific enough (0,1,1) to beat the type selector and re-establishes
the inheritance the author intended. It closes the class rather than
patching the instances: any group carrying `.mono` now passes the
face down, including ones added later. It touches exactly one
property, so it cannot drift the `fill` values #167 just moved, and
it does not restate the font stack — the face stays declared once
per file.
Measured in Chromium at native size across all 102 blog SVGs
(1,944 text nodes): 0 of 46 affected nodes honoured the declared
mono face before, 46 of 46 after, with 0 drift on font-family,
font-size, fill, font-weight, text-anchor and letter-spacing for
every other node. Monospace is wider, so containment was checked
too: all 46 still fit their cards, tightest slack 78.1px, so no
geometry needed revisiting.
Four of the seven files came from the sweep, not the report.
Fixes #165
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeA1nwBz1ohH65dvffUGKr
|
ACCEPT — reviewed against the branch, and looked at. Union I at The mechanism, confirmed independently. Every one of the seven files has at least one That mix is the proof. Rendered before and after at native size in Chromium and compared side by side, seven files after, four before:
Nothing else moved: no geometry, no colour, no font size, no wording. Seven files, seven insertions, seven deletions — one appended declaration per file, on the line that already held
This is the fourth distinct way the house Landing on Generated by Claude Code |
Fixes #165
The mechanism
Each of these assets declares the house face on the element type:
When
.monosits on an ancestor group, the text nodes inside takefont-familyfrom the type selector matching them directly, which outranks the value merely inherited from the group. The monospace face was declared, inherited in principle, and never applied.font-sizeon the same class did land — no competingtext{font-size}rule exists — which is why the blocks looked deliberately sized but wrongly faced.Same mechanism as #140, applied to
font-familyinstead offill. #167 moved colour onto the text nodes and left.monoon the group, so it did not make this redundant.The fix shape, and why this one
One rule per asset, next to the class it repairs:
The ruling allowed either making the class specific enough to win or moving it onto the text nodes (#133's shape). This is the first, and it was chosen because it closes the class rather than patching the instances:
.mononow passes the face down — including ones added later. The alternative edits 46 text nodes and leaves the next.monogroup to fail the same way.(0,1,1)beats the type selector's(0,0,1), andinherittakes the mono stack from the group, so the face is still declared exactly once per file — no duplicated font stack to drift.fillvalues Blog SVGs: give dark-card text an explicit fill so it stops rendering dark-on-dark #167 just moved, norfont-size..monois already on a text node (run-record-en.svguses both forms), the descendant selector does not match it and nothing changes.Diff is 7 lines across 7 files. No wording, geometry, colours or font sizes changed.
Scope: 4 of the 7 files came from the sweep
The issue named three. Sweeping all 102 files under
content/blog/**/*.svgfor the same shape found four more —ai-wrote-your-app-dare-to-merge/cover{,-en}.svgandgive-your-agent-rules-for-governable-apps/cover{,-en}.svg. None of the seven is among the five files #166 holds. Defeated declarations found in the rest of the corpus, including one inside #166's files, are recorded in #180 rather than fixed here — every one of them is a colour or size change.Before / after: computed
font-familyper affected text nodeMeasured in Chromium at native size, all 102 blog SVGs loaded, 1,944 text nodes read.
Honoured before: 0 of 46. Honoured after: 46 of 46.
ai-ontology-open-protocol/one-definition-four-surfaces-en.svg-apple-systemui-monospaceai-ontology-open-protocol/one-definition-four-surfaces.svg-apple-systemui-monospaceai-wrote-your-app-dare-to-merge/cover-en.svg-apple-systemui-monospaceai-wrote-your-app-dare-to-merge/cover.svg-apple-systemui-monospacegive-your-agent-rules-for-governable-apps/cover-en.svg-apple-systemui-monospacegive-your-agent-rules-for-governable-apps/cover.svg-apple-systemui-monospaceobjectos-automation-engine/run-record-en.svg-apple-systemui-monospaceMonospace is wider, so containment was checked rather than assumed: each of the 46 nodes was compared against the card rect behind it. 46 fit, 0 overflow, tightest slack 78.1px (
discount: Field.percent(...),). Nox/yneeded revisiting, so no geometry moved.No collateral change
#167 moved every colour in this corpus, so drift here would be easy to miss. Both
font-familyandfillwere re-measured on every node not targeted by the fix, plusfont-size,font-weight,text-anchorandletter-spacing:font-familychangesThe assets were looked at
All 7 re-rendered at native size in Chromium and inspected, not just measured. The code blocks now read as source; in
run-record-en.svgthe evidence strip finally matches the mono labels beside it that always worked (sys_automation_run,status: paused), which is what made the inconsistency visible in the first place. The Simplified Chinese assets were checked specifically: Latin runs render mono, CJK falls back as it must, and every line still sits inside its card.Gates
Run through the shared verify lock after the final commit, at
47786ad; exit codes captured before any pipe.pnpm content:lint✓ content lint passed (334 files, 44 glossary terms checked)pnpm checkResult (134 files): 0 errors, 0 warnings, 0 hintspnpm build[build] 866 page(s) built in 62.75s·[build] Complete!pnpm seo:smokeSEO smoke test passed (865 HTML pages checked)os-verify-lock: VERDICT command-exit 0 · held the lock 80s · waited 73s.git status --porcelainempty after the run — thegen-zh-hantstep insidebuildregenerated nothing.🤖 Generated with Claude Code
Generated by Claude Code
Generated by Claude Code