MR-F4 S2: (1) commands/newsletter.md Step 7.5 — generate er nå tre ruter; kodet rute (render/build-figur.mjs) er PRIMÆR for data-figurer (presisjon/reproduserbarhet), mcp-image beholdes for illustrative, external uendret. Fasetabell + ressursliste + rute-statuslinje oppdatert. (2) NY references/figure-design-guidelines.md — designregler (24pt, fargebudsjett, whitespace), token-konvensjon (profile/brand-tokens.json, --figur-*, nøytrale defaults), tre render-mål. Refs 27->28. (3) CLAUDE.md Architecture-linje for rendereren. scripts/test-runner.sh: EXPECT_REFS 27->28 + fila navngitt i POSTM0_REFS (named-additions-vakta). Suiter grønne på floor: 138/0 - 140/0 - 35/0 - 53/0 - 245/0 - 134/0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: e70c619c-419b-4229-acaa-b5291f5e75d6
3.4 KiB
Figure Design Guidelines — coded figures
Design rules and conventions for coded figures: SVG/HTML sources rendered to
PNG with ${CLAUDE_PLUGIN_ROOT}/render/build-figur.mjs. Coded is the primary
route for data figures (charts, diagrams, comparisons — anything whose content
is real numbers or real structure): precision and reproducibility beat generative
output, and the figure re-renders identically after a correction. Generative
images (mcp-image) remain the route for illustrative work (cover art, mood,
metaphor). Strategy-level guidance on when a post needs a visual at all lives in
linkedin-visual-style.md.
The three render targets
| Target | Size | Use |
|---|---|---|
article (default) |
1200 × content-driven height (aspect derived from the source's viewBox/dimensions; fallback 16:9) |
inline figures in long-form articles |
carousel |
1080 × 1350 (4:5) | carousel/document-post slides |
single |
1200 × 1200 (1:1) | standalone feed-post image |
--width N / --height N override any target. If an article-target source
declares no dimensions, the renderer warns and falls back to 16:9 — set an
explicit viewBox (SVG) or --height.
node "${CLAUDE_PLUGIN_ROOT}/render/build-figur.mjs" figN.svg --target article --out figN.png
CLI and importable module (renderFigure is async). No npm dependencies; needs
headless Chrome (auto-discovered: app bundle → PATH → error with install hint).
No network access during render — sources must be local and self-contained.
Design rules
Enforced as warn-only validation by the renderer (never a hard fail); treat warnings as a review checklist, not noise:
- Text ≥ 24pt/px effective size. Figures are read on a phone in the feed —
smaller text is illegible at feed scale. (Same floor as the carousel rules in
linkedin-visual-style.md.) - Color budget: max 1 primary + 1 secondary beyond neutrals. Grays, white, and black are free; every additional hue must earn its place. More colors read as noise, not information.
- ≥ 40 % whitespace — an editorial rule, not machine-checked. Density is the most common coded-figure failure. If the figure needs a legend to be parsed, it probably needs to be two figures.
Brand-token convention
The renderer injects design tokens as CSS variables (--figur-*) so figure
sources stay brand-agnostic. Tokens are user data, read from the data root
(see data-path-convention.md):
${LINKEDIN_STUDIO_DATA:-$HOME/.claude/linkedin-studio}/profile/brand-tokens.json
| Key | CSS variable | Neutral default |
|---|---|---|
background |
--figur-background |
#FFFFFF |
ink |
--figur-ink |
#1A1A1A |
muted |
--figur-muted |
#5B5B5B |
accent |
--figur-accent |
#2F6F9F |
rule |
--figur-rule |
#D9D9D9 |
fontFamily |
--figur-fontFamily |
system-ui, -apple-system, 'Helvetica Neue', Arial, sans-serif |
Missing or unparsable file → neutral defaults with a warning. Partial files are
merged over the defaults. The user's brand is data, never hardcoded — figure
sources reference var(--figur-accent) etc. and render correctly for any user.
Authoring rule: use the --figur-* variables for every color and font in a
figure source. A hex value hardcoded in the source defeats the token seam and
counts against the color budget.