@@ -75,322 +75,21 @@ plugin's `writing-clearly-and-concisely` skill before writing prose.
7575
7676If a repo's GitHub visibility is ` PRIVATE ` , it does not appear here. Verify with ` gh repo view OWNER/REPO --json visibility ` when in doubt.
7777
78- ## Diagram style
78+ ## Diagrams
7979
80- Inline ` ```mermaid ` fenced blocks render natively in Mintlify with ELK layout.
81- One diagram per concern — do not combine.
80+ Every repo with non-trivial architecture ships diagrams, rendered as inline
81+ Mermaid. The reader-facing summary — format, placement, what to draw, and when
82+ to reach for a table or ` <Steps> ` instead — is the published page
83+ [ ` conventions/diagramming ` ] ( conventions/diagramming.mdx ) .
8284
83- ### The canonical theme directive (use ** exactly this** , byte-for-byte)
85+ The full authoring rules are split across two canonical pages. Follow both when
86+ you emit any Mermaid on this site:
8487
85- Every Mermaid block on the site MUST begin with this directive. The
86- ` look:'handDrawn' ` is non-negotiable — it gives the diagrams personality
87- that matches the site's voice. Any deviation (different fontSize, missing
88- ` look ` , different palette) is a bug.
89-
90- ``` text
91- %%{init: {'theme':'base','look':'handDrawn','themeVariables':{'fontFamily':'Geist','fontSize':'14px','primaryColor':'#102937','primaryTextColor':'#F4EFE6','primaryBorderColor':'#4FB3A9','lineColor':'#4FB3A9','secondaryColor':'#0B1D2A','tertiaryColor':'#1A2A38','clusterBkg':'rgba(79,179,169,0.08)','clusterBorder':'#4FB3A9'}}}%%
92- ```
93-
94- To check the site is consistent:
95-
96- ``` bash
97- grep -h ' %%{init:' --include=' *.mdx' -r . | sort -u | wc -l
98- # Must return 1.
99- ```
100-
101- ### Shape vocabulary
102-
103- - Stadium ` ([Label]) ` for services and processes
104- - Cylinder ` [(Label)] ` for data stores
105- - Diamond ` {Label} ` for decisions / gates
106- - Circle ` ((Label)) ` for endpoints / external actors
107- - Hexagon ` {{Label}} ` for special-purpose nodes (use sparingly)
108- - Subgraphs for things that physically or logically co-locate
109- (a cluster, a host, a network, a repo group) — ** never** for roles or phases
110-
111- ### Canonical classDef palette
112-
113- Use the semantic class names below. Pick ONE per node based on what it
114- represents; don't invent new classes per page. This keeps the same colour
115- meaning the same idea everywhere.
116-
117- ``` text
118- classDef src fill:#102937,stroke:#E06B4A,stroke-width:2px,color:#F4EFE6;
119- classDef hop fill:#102937,stroke:#4FB3A9,stroke-width:2px,color:#F4EFE6;
120- classDef sink fill:#102937,stroke:#F4EFE6,stroke-width:2px,color:#F4EFE6;
121- classDef gate fill:#102937,stroke:#E06B4A,stroke-width:2.5px,color:#F4EFE6;
122- classDef external fill:#102937,stroke:#E6B35A,stroke-width:2px,color:#F4EFE6;
123- classDef host fill:#102937,stroke:#4FB3A9,stroke-width:2px,color:#F4EFE6;
124- classDef ai fill:#102937,stroke:#E06B4A,stroke-width:2px,color:#F4EFE6;
125- classDef auto fill:#102937,stroke:#F4EFE6,stroke-width:1.5px,color:#F4EFE6;
126- ```
127-
128- All classes share the same dark fill (` #102937 ` ) so the diagram blends
129- with the page; the ** border colour** is what carries the semantic
130- meaning. Text is always paper (` #F4EFE6 ` ) — readable against the dark fill.
131-
132- | Class | Border | Meaning |
133- | --- | --- | --- |
134- | ` src ` / ` ai ` / ` gate ` | Coral ` #E06B4A ` | Origin, AI-touched, or a decision gate. |
135- | ` hop ` / ` host ` | Bright green ` #4FB3A9 ` | Intermediate hops, the parent shell, hosts. |
136- | ` sink ` / ` auto ` | Paper ` #F4EFE6 ` | Sinks (Splunk indexer), automation steps. |
137- | ` external ` | Amber ` #E6B35A ` | External actors (Internet, AWS DR). |
138-
139- ### Canonical edge palette (indexed ` linkStyle ` )
140-
141- ``` text
142- %% physical / network — solid bright green
143- linkStyle 0,1,2 stroke:#4FB3A9,stroke-width:2px;
144-
145- %% data / telemetry — dashed coral
146- linkStyle 3,4 stroke:#E06B4A,stroke-width:2px,stroke-dasharray:4 3;
147-
148- %% control / provisioning — solid paper, lower weight
149- linkStyle 5 stroke:#F4EFE6,stroke-width:1.5px;
150-
151- %% external / DR — dotted amber
152- linkStyle 6 stroke:#E6B35A,stroke-width:1.5px,stroke-dasharray:2 4;
153-
154- %% abort / failure — dashed dark coral
155- linkStyle 7 stroke:#C25638,stroke-width:1.5px,stroke-dasharray:2 4;
156- ```
157-
158- ### Fun touches (consistent across the site)
159-
160- Within the canonical palette, these are ** encouraged** for personality:
161-
162- - ** Mix node shapes** purposefully — stadiums for processes, cylinders
163- for stores, diamonds for decisions, circles for external actors.
164- Variety helps readers parse at a glance.
165- - ** Short labels.** ` claude process ` , not ` the Claude Code subprocess ` .
166- Two lines max (use ` <br/> ` sparingly).
167- - ** Edge labels are fine** when they add information (` "renew leases" ` ,
168- ` "hands off" ` , ` "applies" ` ). Skip them when the chain is obvious.
169- - ** FontAwesome icons** in node labels where they reinforce the shape:
170- ` [fa:fa-shield Security] ` , ` [fa:fa-server Host] ` . Stick to filled
171- variants for visual weight.
172-
173- ## Mermaid — layout rules
174-
175- Before emitting any mermaid block, run the four checks below. If a
176- diagram fails ANY check, redesign it before writing the fence.
177-
178- ### Rule 1 · One narrative shape per diagram
179-
180- Decide which of these four shapes the data IS, then commit to it. If you
181- can't pick one, you have two concerns — split into two diagrams.
182-
183- - ** LINEAR CHAIN** — ` A → B → C → D → E ` . Use ` flowchart LR ` . No subgraphs
184- for "roles" or "phases" (they always cause zigzag). To show role/owner,
185- color nodes via ` classDef ` . Don't put them in columns.
186- - ** PARALLEL CONVERGENCE** — two chains that join at the end. Use
187- ` flowchart LR ` . Declare the longer chain first (its nodes appear higher
188- in source). ELK will rank the shorter chain on the second row.
189- - ** HIERARCHY / TREE** — a parent with grouped children. Use ` flowchart TB ` .
190- Children grouped in subgraphs with ` direction LR ` . Cap subgraph contents
191- at 5 nodes — overflow gets a second subgraph at the same rank.
192- - ** HUB AND SPOKES** — one central node connected to 4–8 leaves. Use
193- ` flowchart LR ` , put leaves in a single subgraph with ` direction TB ` . Do
194- not draw all edges from hub — chain leaves inside the subgraph with
195- invisible ` ~~~ ` links so they stack, then one edge hub → first leaf.
196-
197- ### Rule 2 · Subgraphs are for THINGS that live together, not for ROLES
198-
199- Subgraphs add a visual box. If the box doesn't represent something that
200- physically or logically co-locates, do NOT make it a subgraph.
201-
202- - ** Forbidden** subgraph names: ` Human ` , ` AI ` , ` Automation ` , ` Phase 1 ` ,
203- any role or temporal phase. A workflow that hands off
204- Human → AI → Human → AI draws a zigzag because arrows cross subgraph
205- boundaries N times; visual complexity goes O(n) → O(n²).
206- - ** Allowed** subgraph names — actual co-location: ` Proxmox cluster ` ,
207- ` Cribl tier ` , ` UniFi network ` , ` AWS DR ` , ` Edge ` , ` Infrastructure ` ,
208- ` Configuration ` , ` Nix ` , ` AI Development ` , ` Observability ` .
209- - For role/owner: use ` classDef ` , color the nodes. The chain stays linear.
210-
211- ``` text
212- classDef human fill:#FBF7EE,stroke:#2F7E78,stroke-width:2px;
213- classDef ai fill:#FFE7DC,stroke:#E06B4A,stroke-width:2px;
214- classDef auto fill:#F4EFE6,stroke:#0B1D2A,stroke-width:1.5px;
215- class H1,H3 human
216- class A1,A2,A3 ai
217- class T1,T2,T3 auto
218- ```
219-
220- ### Rule 3 · Density caps — measured, not vibed
221-
222- - Max ** 5 nodes per rank** (per LR column or TB row).
223- - Max ** 5 nodes inside any single subgraph** . 6+ → split into two
224- subgraphs at the same rank.
225- - Max ** 12 nodes per diagram total** . Past 12, you have two diagrams.
226- - Max ** ONE subgraph boundary per edge** . An edge that crosses two
227- boundaries means a subgraph is in the wrong place; reorder source
228- declarations until each edge crosses ≤1 boundary.
229-
230- Aspect-ratio sanity check (mentally render before emitting):
231-
232- - Wider than 2.5:1 → outer direction is wrong (use TB instead)
233- - Taller than 1:1.2 → too many siblings somewhere (cap at 5)
234- - Goal: between 16:9 and 4:3.
235-
236- ### Rule 4 · ` classDef ` always, ` linkStyle ` by index
237-
238- - ** Never emit per-node ` style ` statements.** Always use ` classDef ` . A
239- diagram with 8 identical ` style X fill:... ` lines is a code smell — the
240- 8 nodes share a category; give them a class.
241- - ** Never emit a global ` linkStyle default stroke:#E06B4A ` ** . It paints
242- every edge the same colour and throws away semantic differentiation.
243- Color edges by what they represent, using indexed ` linkStyle ` :
244-
245- ``` text
246- %% edges 0-2 are deployment, edges 3-5 are telemetry
247- linkStyle 0,1,2 stroke:#2F7E78,stroke-width:2px;
248- linkStyle 3,4,5 stroke:#E06B4A,stroke-width:2px,stroke-dasharray:4 3;
249- ```
250-
251- Edge index = declaration order, zero-based. Count carefully.
252-
253- Standard edge palette for this site:
254-
255- | Meaning | Style | Colour |
256- | --- | --- | --- |
257- | Physical / network | solid | ` #2F7E78 ` (deep green) |
258- | Data / telemetry | dashed | ` #E06B4A ` (coral) |
259- | Control / provisioning | solid, lower weight | ` #0B1D2A ` (ink) |
260- | External / DR | dotted | ` #E6B35A ` (amber) |
261-
262- ### Self-check before emitting
263-
264- - [ ] Diagram is one of the four shapes (chain / convergence / hierarchy / hub)
265- - [ ] No subgraph is named for a role (Human, AI, Phase 1, etc.)
266- - [ ] Every rank ≤5 nodes, every subgraph ≤5 nodes, total ≤12
267- - [ ] Every edge crosses ≤1 subgraph boundary
268- - [ ] Zero ` style ` statements; all visual grouping via ` classDef `
269- - [ ] Zero ` linkStyle default ` ; edges colored by semantic category
270- - [ ] Mentally rendered aspect ratio between 4:3 and 16:9
271-
272- If ANY box is unchecked, redesign before responding. Show the self-check
273- as a comment block ABOVE the mermaid fence so a human can verify your
274- reasoning:
275-
276- ``` text
277- %% Shape: linear chain. Boundary crossings: 0. Ranks: 9×1.
278- %% Aspect: ~3:1 (LR). Pass.
279- ```
280-
281- ### When NOT to use Mermaid
282-
283- If the content is a flat list, a comparison, or sequential steps without
284- branching, prefer the native Mintlify primitive instead. Mermaid is for
285- shapes; tables and Steps are for everything else.
286-
287- | Use | When |
288- | --- | --- |
289- | ` <Steps> ` | Sequential process where each step is one action |
290- | Table | Categorisation, comparison, "X column maps to Y column" |
291- | Mermaid | One of the four shapes above; structure ≥ 4 nodes with real edges |
292- | Prose with bold leads | Relationships that read better as a paragraph |
293-
294- ## Mermaid — drill-down links
295-
296- Make diagram nodes navigable. Mintlify honors Mermaid's ` click `
297- directive: each node gets a pointer cursor, a hover tooltip, and
298- navigates on click. This is the canonical way to get "zoom in to a
299- detail page" behaviour on this site — no custom components, no SVG
300- export, no JavaScript.
301-
302- ### When to add clicks
303-
304- Add ` click ` whenever a node represents a topic that has its own
305- detail page on this site or its own canonical external URL (a repo,
306- a dashboard, a vendor doc). This is ** the default for context,
307- overview, and hub diagrams** — not an optional embellishment.
308-
309- Skip clicks for: nodes that don't map to a real destination (a
310- transient process, an abstract concept like "Code" or "Ship"), or
311- destinations that are still TODO and would 404.
312-
313- ### Canonical syntax — INTERNAL links only
314-
315- Use only this form. One ` click ` per line. Always include a tooltip —
316- for hover-only users it's the only signal of where the click goes.
317-
318- ``` text
319- click NodeId "/path/to/internal/page" "Short hover tooltip"
320- ```
321-
322- Place the ` click ` block AFTER all ` classDef ` definitions and ` class `
323- assignments, and BEFORE any ` linkStyle ` lines.
324-
325- ### External URLs — do NOT click them from the diagram
326-
327- Mermaid has open bugs
328- ([ #3077 ] ( https://github.com/mermaid-js/mermaid/issues/3077 ) ,
329- [ #5550 ] ( https://github.com/mermaid-js/mermaid/issues/5550 ) ) where
330- ` _blank ` is parsed but silently dropped from the rendered SVG.
331- Clicking an external link on a node navigates the current tab away —
332- the diagram disappears, the back button is the only way home.
333-
334- Workaround: put external links in a ** table** or ** CardGroup**
335- directly under the diagram. Mintlify automatically adds
336- ` target="_blank" rel="noreferrer" ` to external markdown anchors, so
337- those open in a new tab correctly.
338-
339- Inside the Mermaid block, click ONLY the internal nodes; leave the
340- external-pointing nodes without a ` click ` directive and add an HTML
341- comment naming where the repo lives:
342-
343- ``` text
344- flowchart LR
345- Tool([Tool]) --> Pack([cc-edge-foo])
346- click Tool "/observability/overview" "Tool overview"
347- %% No click on Pack — external repo lives in the table below.
348- ```
349-
350- Then the table directly under the diagram carries the external link:
351-
352- ``` text
353- | Repo | Notes |
354- | --- | --- |
355- | [cc-edge-foo](https://github.com/owner/cc-edge-foo) | What it does |
356- ```
357-
358- When the Mermaid bugs are fixed upstream, this convention will
359- expand to allow external clicks; until then, internal-only.
360-
361- ### Self-check addition
362-
363- Append these to the existing self-check before emitting any context,
364- overview, or hub diagram:
365-
366- - [ ] Every node whose label names a topic with a detail page has a ` click ` line
367- - [ ] All ` click ` URLs are site-relative paths (` /security/overview ` ), never external ` https://... `
368- - [ ] External repo URLs live in a table or CardGroup beside the diagram, NOT in ` click ` directives
369- - [ ] Tooltips are ≤40 chars and describe the destination (not the node)
370- - [ ] No ` click ` points at a page that doesn't exist yet (would 404)
371- - [ ] CI Mermaid validation passes (` ./scripts/validate-mermaid.sh ` from repo root)
372-
373- ### Example
374-
375- ``` text
376- flowchart LR
377- Ovr([Overview]) --> Detail([Detail page])
378- classDef hop fill:#102937,stroke:#4FB3A9,stroke-width:2px,color:#F4EFE6;
379- class Ovr,Detail hop
380- click Ovr "/overview" "Read the full overview"
381- click Detail "/overview/detail" "The deep dive"
382- ```
383-
384- ### When NOT to use clicks
385-
386- - ** Pure sequence / timeline diagrams** where every node is a stage
387- in one flow (e.g. CI step "Lint") — clicks would imply each stage
388- has its own page when the whole pipeline is one page.
389- - ** Diagrams in repo READMEs that render on GitHub.** GitHub's
390- Mermaid renderer honors ` click ` differently and absolute URLs are
391- required there. Keep site-relative click diagrams on
392- docs.jacobpevans.com; if a README needs an interactive diagram,
393- link out to the relevant docs page instead.
88+ - [ ` conventions/mermaid-style ` ] ( conventions/mermaid-style.mdx ) — the byte-for-byte
89+ theme directive, shape vocabulary, ` classDef ` and ` linkStyle ` palettes, the four
90+ narrative shapes, and density caps.
91+ - [ ` conventions/mermaid-links ` ] ( conventions/mermaid-links.mdx ) — making diagram
92+ nodes navigable with the ` click ` directive, and the external-URL workaround.
39493
39594## Phases
39695
0 commit comments