feat(diagrams): resolve every diagram color from tokens, at paint time - #12646
Conversation
|
This pull request is part of a Mergify stack:
|
Merge Protections🟢 All 6 merge protections satisfied — ready to merge. Show 6 satisfied protections🟢 🤖 Continuous Integration
🟢 👀 Review Requirements
🟢 Enforce conventional commitMake sure that we follow https://www.conventionalcommits.org/en/v1.0.0/
🟢 🔎 Reviews
🟢 📕 PR description
🟢 🚦 Auto-queueWhen all merge protections are satisfied, this pull request will be queued automatically. |
There was a problem hiding this comment.
🔵 Needs a closer look
It introduces broad styling and rendering behavior changes across all diagrams that require careful visual verification in both themes in addition to unit tests.
Pull request overview
This PR refactors Graphviz diagram rendering so diagrams emit semantic role classes (no inline paint) and are fully styled at paint time via CSS tokens, enabling consistent theming (including dark mode) without per-diagram hardcoded colors.
Changes:
- Introduces diagram role accent tokens in
theme.css(plus a new docs-only--color-green-700primitive) and derives diagram surfaces/borders/labels viacolor-mix()at paint time. - Replaces legacy
svg.graphstyling with a.dgstylesheet that paints nodes/edges/clusters/captions based on roles. - Reworks
remark-graphvizto inject layout defaults, strip inline paint, map legacy colors to roles, and adds a Vitest suite to lock down the new behavior.
File summaries
| File | Description |
|---|---|
| src/styles/tokens.css | Adds a docs-only primitive token --color-green-700 used by the diagram role palette. |
| src/styles/theme.css | Defines diagram role accent variables and theme-dependent mixing parameters (light/dark). |
| src/styles/index.css | Implements .dg paint-time styling rules for Graphviz SVG output, including role mapping and caption/plain-node handling. |
| plugins/remark-graphviz.ts | Updates the Graphviz remark plugin to inject defaults, remove inline paint, assign role classes, and set the .dg class. |
| plugins/remark-graphviz.test.ts | Adds unit tests covering role mapping, paint stripping, canvas removal, overrides, and failure behavior. |
| DESIGN.md | Documents the additional non-product token and clarifies token policy wording. |
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
The diagrams were not ugly because Graphviz is ugly. They were ugly because 63 hand-typed colors across 18 pages had no palette to be consistent with, and their dark mode was a hardcoded list of six strings the plugin string-matched. Four dialects had grown — queue-green, emoji-pastel, nineties-pastel and near-white-blueprint — and `enterprise/architecture` rendered as a stack of white slabs on the dark page, because the plugin deliberately skips a cluster that has a fill and every fill on that page is near-white. Graphviz supports a `class` attribute on graphs, nodes, edges and clusters and copies it verbatim into the SVG. So the plugin stops handling color entirely. It injects shape and spacing defaults, drops the opaque canvas, tags each element with a *role*, strips the inline paint, and one stylesheet resolves surface, border and label at paint time. Dark mode then arrives through the same `:root.theme-dark` block as every other surface on the site — no second render, no flash, no string matching — and the built SVGs now contain no color at all. The 19 fences are not touched. A table in the plugin maps the colors the docs were drawn with onto roles, so the whole corpus is recolored with zero MDX edits and this reverts in one commit. The table maps by hue family, so elements drawn alike still read alike; it is lossy the other way — PostgreSQL and Redis both land on `datastore` — and that is paid back one page at a time as each fence names its own roles. It is a shim with a known end: when no fence spells a color, nothing reaches it. Three things change that are worth knowing before reviewing screenshots: - A graph-level caption moves above the figure. Graphviz's default is below; `labelloc="t"` is injected, so every fence with a `label=` that does not set `labelloc` itself now captions on top. - Diagram text is painted in Inter rather than the browser's default sans. Graphviz still measures in Helvetica, so widths drift by about 3%; the injected node margins absorb it. - Borders lift toward white in dark mode. The product accents themselves are untouched, as DESIGN.md requires — what changes is a value derived from them, because a #347d39 outline on the dark page surface is too dim to read. Two roles deliberately share an accent (`queued` and `mergify` are both Merge Queue teal): the same color under two names, because "waiting in the queue" and "a service we run" are the same idea on two kinds of diagram, and a role name that lies is worse than a duplicated accent. `--color-green-700` is not a new color. It is the green nine diagrams already had hardcoded, promoted so it has a name. Verified by rendering all 35 diagrams on the site in both themes and comparing them against the same page before the change. Change-Id: I4100df168b1a98d79cd2f0eca15697cb2a9db1cb
65e6056 to
3b720e0
Compare
Revision history
|
Merge Queue Status
This pull request spent 3 minutes 40 seconds in the queue, including 2 minutes 35 seconds running CI. Required conditions to merge
|
The diagrams were not ugly because Graphviz is ugly. They were ugly because 63
hand-typed colors across 18 pages had no palette to be consistent with, and
their dark mode was a hardcoded list of six strings the plugin string-matched.
Four dialects had grown — queue-green, emoji-pastel, nineties-pastel and
near-white-blueprint — and
enterprise/architecturerendered as a stack ofwhite slabs on the dark page, because the plugin deliberately skips a cluster
that has a fill and every fill on that page is near-white.
Graphviz supports a
classattribute on graphs, nodes, edges and clusters andcopies it verbatim into the SVG. So the plugin stops handling color entirely.
It injects shape and spacing defaults, drops the opaque canvas, tags each
element with a role, strips the inline paint, and one stylesheet resolves
surface, border and label at paint time. Dark mode then arrives through the
same
:root.theme-darkblock as every other surface on the site — no secondrender, no flash, no string matching — and the built SVGs now contain no color
at all.
The 19 fences are not touched. A table in the plugin maps the colors the docs
were drawn with onto roles, so the whole corpus is recolored with zero MDX
edits and this reverts in one commit. The table maps by hue family, so elements
drawn alike still read alike; it is lossy the other way — PostgreSQL and Redis
both land on
datastore— and that is paid back one page at a time as eachfence names its own roles. It is a shim with a known end: when no fence spells
a color, nothing reaches it.
Three things change that are worth knowing before reviewing screenshots:
labelloc="t"is injected, so every fence with alabel=that does not setlabellocitself now captions on top.Graphviz still measures in Helvetica, so widths drift by about 3%; the
injected node margins absorb it.
untouched, as DESIGN.md requires — what changes is a value derived from them,
because a #347d39 outline on the dark page surface is too dim to read.
Two roles deliberately share an accent (
queuedandmergifyare both MergeQueue teal): the same color under two names, because "waiting in the queue"
and "a service we run" are the same idea on two kinds of diagram, and a role
name that lies is worse than a duplicated accent.
--color-green-700is not a new color. It is the green nine diagrams alreadyhad hardcoded, promoted so it has a name.
Verified by rendering all 35 diagrams on the site in both themes and comparing
them against the same page before the change.