Establishes mandatory standards for Mermaid diagrams in Blue documents: - Neutral theme required for dark/light mode compatibility - Leaf node counting for LR flow warnings (>3 nodes) - Plain text for architecture labels (no emoji color injection) - Shape semantics advisory for new diagrams - Auto-fix for theme declaration only (colors require manual review) Includes alignment dialogue with 10/10 tensions resolved across 3 rounds. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
6.2 KiB
Spike: Mermaid Diagram Style Guide for Blue Documents
| Status | Done |
| Date | 2026-01-30 |
| Time Box | 30 minutes |
Question
How can we ensure Mermaid diagrams in Blue documents are readable in both light and dark modes, prefer vertical flow, and have consistent styling?
Problem Analysis
From the screenshot, the current diagram has these issues:
- Subgraph labels unreadable — "Superviber Control Plane" and "Client Infrastructure" use dark text on colored backgrounds
- Fill colors designed for light mode —
#e8f5e9,#e3f2fd,#fff3e0are light pastels that look washed out in dark mode - Node text invisible — Dark nodes (
#333) have no explicit text color - Horizontal sprawl — Some diagrams use
LRwhenTBwould be more readable
Mermaid Theme Options
Option A: Use dark Theme
%%{init: {'theme': 'dark'}}%%
flowchart TB
A[Node A] --> B[Node B]
Problem: Still doesn't control subgraph label colors well.
Option B: Use base Theme with Custom Variables
%%{init: {
'theme': 'base',
'themeVariables': {
'primaryColor': '#4a5568',
'primaryTextColor': '#fff',
'primaryBorderColor': '#718096',
'lineColor': '#718096',
'secondaryColor': '#2d3748',
'tertiaryColor': '#1a202c'
}
}}%%
Problem: Verbose, must repeat in every diagram.
Option C: Use neutral Theme (Recommended)
%%{init: {'theme': 'neutral'}}%%
flowchart TB
subgraph SV["Superviber Control Plane"]
ORCH[Orchestration]
BILL[Billing]
end
Benefit: Works in both light and dark modes. Grayscale palette avoids color contrast issues.
Recommended Style Guide
1. Always Use neutral Theme
%%{init: {'theme': 'neutral'}}%%
flowchart TB
...
2. Prefer Top-to-Bottom Flow (TB)
flowchart TB ← vertical flow
Not:
flowchart LR ← horizontal, requires scrolling
3. Avoid Custom Fill Colors
Don't do this:
style CLIENT fill:#e8f5e9
Do this instead:
%% Let neutral theme handle colors
%% Use node shapes for visual distinction
4. Use Subgraph Labels Without Styling
subgraph CLIENT["Client Infrastructure"]
%% No style directive needed
end
5. Use Shape Variations for Distinction
| Shape | Syntax | Use Case |
|---|---|---|
| Rectangle | [text] |
Services, components |
| Rounded | (text) |
User-facing elements |
| Database | [(text)] |
Data stores |
| Stadium | ([text]) |
External systems |
| Hexagon | {{text}} |
Decision points |
6. Keep Edge Labels Short
A -->|"mTLS"| B ← good
A -->|"Mutual TLS encrypted connection over port 443"| B ← too long
Example: ADR 0017 Diagram Rewritten
Before (problematic)
flowchart TB
subgraph CLIENT["Client Infrastructure"]
AGENT["Superviber Agent<br/>(Claude Code)"]
CODE[("Source Code<br/>Credentials<br/>Secrets")]
end
subgraph SV["Superviber Control Plane"]
ORCH["Orchestration"]
BILL["Billing"]
TELEM["Telemetry"]
end
style CLIENT fill:#e8f5e9
style SV fill:#e3f2fd
After (neutral theme, readable)
%%{init: {'theme': 'neutral'}}%%
flowchart TB
subgraph USER["Developer"]
WEB["Web Interface"]
end
subgraph SV["Superviber Control Plane"]
ORCH["Orchestration"]
BILL["Billing"]
TELEM["Telemetry"]
end
subgraph CLIENT["Client Infrastructure"]
AGENT["Superviber Agent"]
CODE[("Source Code<br/>Credentials")]
end
WEB -->|"Session"| ORCH
ORCH -->|"Route"| AGENT
AGENT <-->|"Local"| CODE
AGENT -->|"Metrics"| TELEM
TELEM --> BILL
Implementation Options
Option 1: Style Guide Only (Documentation)
Add to .blue/docs/style-guide.md:
- Always use
%%{init: {'theme': 'neutral'}}%% - Prefer
flowchart TB - Avoid custom
styledirectives
Pros: Simple, no tooling Cons: Relies on authors remembering
Option 2: Lint Rule
Add to blue_lint:
// Check for Mermaid blocks missing neutral theme
if mermaid_block && !contains("theme': 'neutral'") {
warn("Mermaid diagram should use neutral theme for dark mode compatibility")
}
Pros: Automated enforcement Cons: Requires implementation
Option 3: Pre-render with Consistent Theme
Use mmdc CLI to pre-render all Mermaid to SVG/PNG with fixed theme at build time.
Pros: Guaranteed consistency Cons: Loses live preview in editors
Decision
Chosen approach: Option C (neutral theme) + Option 2 (Lint rule)
Why neutral Theme
- Works in both light and dark modes without customization
- Grayscale palette avoids color contrast issues
- No need to repeat verbose
themeVariablesin every diagram - Subgraph labels are readable by default
Lint Rule Specification
Add to blue_lint:
/// Checks Mermaid code blocks for neutral theme declaration
fn lint_mermaid_theme(content: &str) -> Vec<LintWarning> {
let mut warnings = vec![];
// Find all mermaid code blocks
for (line_num, block) in find_mermaid_blocks(content) {
if !block.contains("'theme': 'neutral'") && !block.contains("\"theme\": \"neutral\"") {
warnings.push(LintWarning {
line: line_num,
message: "Mermaid diagram should use neutral theme: %%{init: {'theme': 'neutral'}}%%".into(),
severity: Severity::Warning,
});
}
}
warnings
}
Implementation Tasks
- ✅ Document decision — This spike
- ⬜ Update ADR 0017 — Apply neutral theme to diagram
- ⬜ Add lint rule — Implement in
blue_lintcrate - ⬜ Create style guide — Add
.blue/docs/mermaid-style-guide.md
Quick Reference Card
## Blue Mermaid Cheatsheet
Always start with:
```mermaid
%%{init: {'theme': 'neutral'}}%%
flowchart TB
```
Shapes:
- [Rectangle] — services
- (Rounded) — user-facing
- [(Database)] — data stores
- {{Hexagon}} — decisions
Don't use:
- style X fill:#color
- flowchart LR (prefer TB)
- Long edge labels
Investigation by Blue