@diagrammo/dgmo 0.15.1 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/README.md +9 -9
  2. package/dist/advanced.cjs +612 -734
  3. package/dist/advanced.d.cts +42 -36
  4. package/dist/advanced.d.ts +42 -36
  5. package/dist/advanced.js +612 -733
  6. package/dist/auto.cjs +508 -620
  7. package/dist/auto.js +105 -105
  8. package/dist/auto.mjs +508 -620
  9. package/dist/cli.cjs +144 -144
  10. package/dist/editor.cjs +8 -9
  11. package/dist/editor.js +8 -9
  12. package/dist/highlight.cjs +8 -9
  13. package/dist/highlight.js +8 -9
  14. package/dist/index.cjs +497 -608
  15. package/dist/index.js +497 -608
  16. package/dist/internal.cjs +612 -734
  17. package/dist/internal.d.cts +42 -36
  18. package/dist/internal.d.ts +42 -36
  19. package/dist/internal.js +612 -733
  20. package/dist/pert.d.cts +2 -2
  21. package/dist/pert.d.ts +2 -2
  22. package/docs/language-reference.md +97 -84
  23. package/docs/migration-sequence-color-to-tags.md +1 -1
  24. package/gallery/fixtures/area.dgmo +3 -3
  25. package/gallery/fixtures/bar-stacked.dgmo +5 -5
  26. package/gallery/fixtures/boxes-and-lines.dgmo +2 -2
  27. package/gallery/fixtures/c4-full.dgmo +8 -8
  28. package/gallery/fixtures/class-full.dgmo +2 -2
  29. package/gallery/fixtures/doughnut.dgmo +6 -6
  30. package/gallery/fixtures/flowchart-colors.dgmo +3 -3
  31. package/gallery/fixtures/function.dgmo +3 -3
  32. package/gallery/fixtures/gantt-full.dgmo +9 -9
  33. package/gallery/fixtures/gantt.dgmo +7 -7
  34. package/gallery/fixtures/infra-full.dgmo +6 -6
  35. package/gallery/fixtures/infra.dgmo +2 -2
  36. package/gallery/fixtures/kanban.dgmo +9 -9
  37. package/gallery/fixtures/line.dgmo +2 -2
  38. package/gallery/fixtures/multi-line.dgmo +3 -3
  39. package/gallery/fixtures/org-full.dgmo +6 -6
  40. package/gallery/fixtures/quadrant.dgmo +2 -2
  41. package/gallery/fixtures/sankey.dgmo +9 -9
  42. package/gallery/fixtures/scatter.dgmo +3 -3
  43. package/gallery/fixtures/sequence-tags-protocols.dgmo +11 -11
  44. package/gallery/fixtures/sequence-tags.dgmo +10 -10
  45. package/gallery/fixtures/sequence.dgmo +4 -4
  46. package/gallery/fixtures/sitemap-full.dgmo +7 -7
  47. package/gallery/fixtures/slope.dgmo +5 -5
  48. package/gallery/fixtures/spr-eras.dgmo +9 -9
  49. package/gallery/fixtures/timeline.dgmo +3 -3
  50. package/gallery/fixtures/venn.dgmo +3 -3
  51. package/package.json +7 -3
  52. package/src/advanced.ts +0 -1
  53. package/src/auto/index.ts +2 -2
  54. package/src/boxes-and-lines/layout.ts +1 -2
  55. package/src/boxes-and-lines/renderer.ts +5 -1
  56. package/src/c4/parser.ts +2 -2
  57. package/src/c4/renderer.ts +15 -8
  58. package/src/chart.ts +18 -9
  59. package/src/class/parser.ts +8 -7
  60. package/src/class/renderer.ts +17 -6
  61. package/src/cli.ts +8 -8
  62. package/src/completion.ts +14 -17
  63. package/src/cycle/parser.ts +15 -1
  64. package/src/cycle/renderer.ts +6 -3
  65. package/src/d3.ts +88 -49
  66. package/src/diagnostics.ts +20 -0
  67. package/src/echarts.ts +28 -11
  68. package/src/editor/dgmo.grammar +1 -3
  69. package/src/editor/dgmo.grammar.d.ts +1 -1
  70. package/src/editor/dgmo.grammar.js +8 -8
  71. package/src/editor/dgmo.grammar.terms.js +11 -12
  72. package/src/editor/highlight-api.ts +0 -1
  73. package/src/editor/highlight.ts +0 -1
  74. package/src/er/parser.ts +19 -12
  75. package/src/er/renderer.ts +19 -7
  76. package/src/gantt/parser.ts +1 -1
  77. package/src/gantt/renderer.ts +7 -4
  78. package/src/graph/flowchart-parser.ts +18 -84
  79. package/src/graph/flowchart-renderer.ts +6 -8
  80. package/src/graph/layout.ts +0 -2
  81. package/src/graph/state-parser.ts +17 -62
  82. package/src/graph/state-renderer.ts +3 -8
  83. package/src/infra/parser.ts +21 -11
  84. package/src/infra/renderer.ts +8 -6
  85. package/src/journey-map/parser.ts +11 -4
  86. package/src/journey-map/renderer.ts +3 -1
  87. package/src/kanban/parser.ts +11 -7
  88. package/src/kanban/renderer.ts +3 -1
  89. package/src/mindmap/parser.ts +4 -5
  90. package/src/mindmap/renderer.ts +2 -1
  91. package/src/org/parser.ts +3 -3
  92. package/src/org/renderer.ts +4 -3
  93. package/src/pert/analyzer.ts +10 -10
  94. package/src/pert/layout.ts +1 -1
  95. package/src/pert/parser.ts +8 -8
  96. package/src/pert/renderer.ts +7 -2
  97. package/src/pert/types.ts +1 -1
  98. package/src/pyramid/parser.ts +13 -1
  99. package/src/raci/parser.ts +42 -12
  100. package/src/raci/renderer.ts +2 -1
  101. package/src/raci/types.ts +4 -3
  102. package/src/ring/parser.ts +13 -1
  103. package/src/sequence/parser.ts +81 -23
  104. package/src/sequence/participant-inference.ts +18 -181
  105. package/src/sequence/renderer.ts +48 -137
  106. package/src/sitemap/layout.ts +0 -2
  107. package/src/sitemap/parser.ts +12 -38
  108. package/src/sitemap/renderer.ts +13 -13
  109. package/src/sitemap/types.ts +0 -1
  110. package/src/tech-radar/parser.ts +2 -2
  111. package/src/tech-radar/renderer.ts +5 -3
  112. package/src/tech-radar/types.ts +2 -0
  113. package/src/utils/arrows.ts +3 -28
  114. package/src/utils/extract-alias.ts +1 -1
  115. package/src/utils/inline-markdown.ts +1 -1
  116. package/src/utils/legend-d3.ts +12 -6
  117. package/src/utils/legend-layout.ts +1 -1
  118. package/src/utils/legend-types.ts +1 -1
  119. package/src/utils/parsing.ts +64 -35
  120. package/src/utils/tag-groups.ts +98 -18
  121. package/src/utils/time-ticks.ts +1 -1
  122. package/src/wireframe/parser.ts +3 -3
package/dist/pert.d.cts CHANGED
@@ -12,7 +12,7 @@ interface DgmoError {
12
12
  code?: string;
13
13
  }
14
14
 
15
- /** A single entry inside a tag group: `Value(color)` */
15
+ /** A single entry inside a tag group: `Value color` */
16
16
  interface TagEntry {
17
17
  value: string;
18
18
  color: string;
@@ -248,7 +248,7 @@ interface ParsedPert {
248
248
  groups: PertGroup[];
249
249
  /**
250
250
  * Tag groups declared at the top of the diagram (`tag Priority as p
251
- * High(red), Low(green)`). Drive node fill via `resolveTagColor()`.
251
+ * High red, Low green`). Drive node fill via `resolveTagColor()`.
252
252
  * Empty when no `tag` blocks are declared.
253
253
  */
254
254
  tagGroups: TagGroup[];
package/dist/pert.d.ts CHANGED
@@ -12,7 +12,7 @@ interface DgmoError {
12
12
  code?: string;
13
13
  }
14
14
 
15
- /** A single entry inside a tag group: `Value(color)` */
15
+ /** A single entry inside a tag group: `Value color` */
16
16
  interface TagEntry {
17
17
  value: string;
18
18
  color: string;
@@ -248,7 +248,7 @@ interface ParsedPert {
248
248
  groups: PertGroup[];
249
249
  /**
250
250
  * Tag groups declared at the top of the diagram (`tag Priority as p
251
- * High(red), Low(green)`). Drive node fill via `resolveTagColor()`.
251
+ * High red, Low green`). Drive node fill via `resolveTagColor()`.
252
252
  * Empty when no `tag` blocks are declared.
253
253
  */
254
254
  tagGroups: TagGroup[];
@@ -59,14 +59,15 @@ These patterns are shared across all or most diagram types.
59
59
 
60
60
  ```
61
61
  tag GroupName as <alias>
62
- Value1(color)
63
- Value2(color) [default]
62
+ Value1 color
63
+ Value2 color
64
64
  ```
65
65
 
66
66
  - `tag` keyword, NO colon
67
67
  - Alias: optional postfix `as <alias>` per §2A (universal alias syntax — `[A-Za-z][A-Za-z0-9_]{0,11}`)
68
- - Inline values also supported: `tag Priority as p Low(green), High(red)`
69
- - First entry is default unless another is marked `default`
68
+ - Inline values also supported: `tag Priority as p Low green, High red`
69
+ - Color follows the value as a bare trailing token (see §1.5). Capitalize the color word (`Red`, `Yellow`) to keep it as a literal value with no color.
70
+ - First entry is the default — reorder to change
70
71
  - Must appear before diagram content
71
72
  - Legacy bare shorthand (`tag Priority p`) and `alias` keyword (`tag Priority alias p`) emit `E_TAG_SHORTHAND_REMOVED` per TD-18
72
73
 
@@ -85,15 +86,36 @@ EntityName | key: value, key2: value2
85
86
 
86
87
  ### 1.5 Color Suffixes
87
88
 
89
+ Color is set by typing the color name at the end of a label, lowercase. Example: `Done green` colors Done green. Eleven colors exist: `red`, `orange`, `yellow`, `green`, `blue`, `purple`, `teal`, `cyan`, `gray`, `black`, `white`. To use a color word as a literal label, capitalize it: `Red` stays as the word `Red`.
90
+
91
+ ```
92
+ Label color // bare trailing color token
93
+ Done green // value=Done, color=green
94
+ Senior Engineer red // value="Senior Engineer", color=red
95
+ Red // value=Red, no color (capitalized → escape hatch)
96
+ ```
97
+
98
+ **The universal rule** — color trails the label:
99
+
100
+ > Color is the trailing whitespace-delimited token of a label region, when that token (case-sensitive, lowercase) is one of the 11 names above. Otherwise the label region has no color.
101
+
102
+ The "label region" is everything left after the parser strips off structural terminators it owns: `as <alias>`, `| <pipe metadata>`, numeric values, date ranges, structural brackets. Parsers split those off BEFORE invoking the color rule. So `Tortuga Distillery orange 3000` → `{ label: "Tortuga Distillery", color: "orange", value: 3000 }`: numeric value first, then the color trails the remaining label.
103
+
104
+ **Where the rule applies**: tag values, kanban columns (`[Done] green`), venn / quadrant items (color before `as`), gantt / timeline eras and markers, data-chart series + rows, sankey nodes + link lines, cycle / pyramid / ring / RACI / boxes-and-lines node labels (shortcut for `| color: <name>` when color is the only metadata).
105
+
106
+ **Long form preserved for multi-key pipe metadata**:
107
+
88
108
  ```
89
- Label(colorName)
109
+ Spring | color: green // shortcut and long form are equivalent
110
+ Spring | color: green, icon: ❄ // long form REQUIRED when other keys accompany color
90
111
  ```
91
112
 
92
- - **Allowed color names (exactly these 10):** `red`, `orange`, `yellow`, `green`, `blue`, `purple`, `teal`, `cyan`, `lightblue`, `gray`
93
- - Any other value — including hex codes (`#ff0000`), CSS keywords (`black`, `white`, `pink`), or typos — is a parse error and produces an inline diagnostic in the editor (with a "did you mean?" suggestion when close to a known name)
94
- - The actual hex value rendered for each name comes from the active palette/theme; users cannot extend or override the allowed list
95
- - Appears at end of labels, node names, tag values, series names
96
- - Color is stripped from display text
113
+ **Accepted tradeoffs**:
114
+
115
+ - **No typo diagnostics**: `Done grren` is a 2-word label with no color, no warning.
116
+ - **Case-sensitivity is the escape hatch**: `Red`, `Yellow`, `Green` stay as labels.
117
+ - **No edge color** on flowchart, state, sitemap. Sankey links DO accept a trailing color word after the numeric value.
118
+ - **11-name palette is a frozen public contract**: adding a 12th color is itself a breaking change.
97
119
 
98
120
  ### 1.6 Indentation
99
121
 
@@ -104,12 +126,12 @@ Label(colorName)
104
126
 
105
127
  ```
106
128
  [Group Name]
107
- [Group Name](color)
129
+ [Group Name] color
108
130
  [Group Name] | key: value
109
131
  ```
110
132
 
111
133
  - Bracket-enclosed name
112
- - Optional color suffix
134
+ - Optional trailing-token color (kanban columns, scatter categories, era/marker labels)
113
135
  - Optional pipe metadata (outside brackets)
114
136
  - Indented content below belongs to the group
115
137
 
@@ -162,7 +184,7 @@ A -日本語-> B
162
184
  A -🎉-> B
163
185
 
164
186
  // punctuation is literal — no markdown interpretation
165
- A -(parenthetical)-> B // label = "(parenthetical)" (NOT a color)
187
+ A -(parenthetical)-> B // label = "(parenthetical)"
166
188
  A -*emphasis*-> B // label = "*emphasis*" (NOT bold)
167
189
  A -`code`-> B // label = "`code`" (NOT a code span)
168
190
 
@@ -185,23 +207,21 @@ A -Makes calls-> B | tech: HTTP // preferred: technology on target metadata
185
207
  - **Plain text only**: no markdown interpretation. `*foo*` renders as `*foo*`, not italicized. `[label](url)` renders as literal `[label](url)`, not a hyperlink. Clickable URLs belong in notes, not in in-arrow labels.
186
208
  - **HTML-safe**: all renderers emit label text as a DOM text node. `<script>alert(1)</script>` renders as literal text — the entire label is a sequence of codepoints, not a markup fragment.
187
209
 
188
- #### Color suffix (flowchart and state only)
210
+ #### Edge color is not a feature
211
+
212
+ Edges on flowchart, state, and sitemap diagrams have NO color slot. `A -(red)-> B` is a literal label with text `(red)`; `A -yes-> B` and `A -no-> B` no longer auto-color the arrow. Arrows render with the default theme color, period. To color a *node*, use tags (§1.3).
213
+
214
+ Sankey link lines DO accept a trailing-token color, because the link itself carries data:
189
215
 
190
216
  ```
191
- A -(red)-> B // colored edge, no label
192
- A -(notacolor)-> B // label = "(notacolor)" (fall-through)
193
- A -(red) uses-> B // label = "(red) uses" (combined form not supported)
194
- A -red-> B // label = "red" (bare word is always a label)
217
+ Sugar Plantations -> Tortuga Distillery 3000 red // link is colored red
195
218
  ```
196
219
 
197
- A parenthesized palette color is only recognized when the entire label between the opening `-` and the arrow token is exactly `(colorName)` and `colorName` is one of the 11 names in §1.5. Any other content falls through to the label. To combine a color and a label, use the post-colon or pipe-metadata form instead.
198
-
199
220
  #### Migrating from pre-gauntlet syntax
200
221
 
201
- Two legacy forms changed with this spec:
222
+ One legacy form changed with this spec:
202
223
 
203
224
  1. **C4 trailing `[technology]` sugar is removed.** A C4 arrow like `-Makes calls [HTTPS]-> API` used to extract `HTTPS` as the technology annotation. The full `Makes calls [HTTPS]` is now the label. Use the post-colon or pipe form for technology: `-Makes calls-> API | tech: HTTPS`.
204
- 2. **Bare palette color suffixes are a literal label.** `A -red-> B` on flowchart/state used to be accepted as a bare color suffix in some surfaces. It is now always a label with text `red`. To color an edge, use the `-(red)->` parens form.
205
225
 
206
226
  No code migration is required for in-arrow label character escaping — any label that was valid before remains valid, with one exception: if your label happened to contain the literal substring `->` or `~>`, the parser now rejects it with `E_ARROW_SUBSTRING_IN_LABEL`. Move those labels to the post-colon form.
207
227
 
@@ -243,7 +263,7 @@ quote.
243
263
 
244
264
  ### 2.3 Examples
245
265
 
246
- - `Auth Service is a service` — bare multi-word, no quoting needed
266
+ - `Auth Database is a database` — bare multi-word, no quoting needed
247
267
  - `"first name" varchar` — quote when name contains a reserved char (the `:` ER type separator)
248
268
  - `"Order | Items"` — quote the pipe
249
269
  - `class "Customer Service"` — bare multi-word also accepts in class
@@ -269,6 +289,7 @@ These are intentionally outside the universal rule:
269
289
  - `I_NAME_MERGED` (warning) — two source-distinct names normalize to the same key with different displayed forms
270
290
  - `E_NAME_RESERVED_CHAR` (error) — bare name contains a reserved char without quoting
271
291
  - `E_AKA_REMOVED` (error) — removed `aka` keyword used in sequence participant declaration
292
+ - `E_PARTICIPANT_TYPE_REMOVED` (error) — sequence `is a X` declaration used a removed type keyword (`service`, `frontend`, `networking`, `gateway`, `external`)
272
293
 
273
294
  ---
274
295
 
@@ -282,7 +303,7 @@ tag-shorthand and venn `alias` keyword forms with a uniform rule.
282
303
 
283
304
  ```
284
305
  sequence
285
- Alice is a service as a
306
+ Alice is an actor as a
286
307
  Bob is a database as b
287
308
  a -hello-> b
288
309
  b -ack-> a
@@ -290,8 +311,8 @@ b -ack-> a
290
311
 
291
312
  ```
292
313
  venn
293
- Swordsmanship(red) as sw
294
- Navigation(blue) as nav
314
+ Swordsmanship red as sw
315
+ Navigation blue as nav
295
316
  sw + nav Sea Raiders
296
317
  ```
297
318
 
@@ -304,7 +325,7 @@ tag Concern as c
304
325
 
305
326
  - **Token shape**: `[A-Za-z][A-Za-z0-9_]{0,11}` — letter start,
306
327
  letters/digits/underscore, length 1–12. **Case-sensitive**.
307
- - **Modifier order on declarations**: `<name> [(color)] [is a type] as <alias> [| key: value, …]`.
328
+ - **Modifier order on declarations**: `<name> [color] [is a type] as <alias> [| key: value, …]`.
308
329
  - **Strict ordering**: aliases must be declared on or before first use.
309
330
  - **Flat global namespace**: one alias literal has exactly one binding per source.
310
331
  - **Aliases are NEVER UNH-normalized** — exact-match short-codes only.
@@ -328,7 +349,7 @@ rarely benefit. Aliases should aid comprehension, not obscure it.
328
349
  |-----|-----|
329
350
  | `tag Priority p` (bare shorthand) | `tag Priority as p` |
330
351
  | `tag Priority alias p` (explicit) | `tag Priority as p` |
331
- | `Swordsmanship(red) alias sw` (venn) | `Swordsmanship(red) as sw` |
352
+ | `Swordsmanship red alias sw` (venn) | `Swordsmanship red as sw` |
332
353
 
333
354
  ### 2A.6 Error Codes
334
355
 
@@ -356,43 +377,38 @@ Name is a <type> [position N]
356
377
  Name | key: value
357
378
  ```
358
379
 
359
- Types: `service`, `database`, `actor`, `queue`, `cache`, `gateway`, `external`, `networking`, `frontend`
380
+ Types: `actor`, `database`, `cache`, `queue` (plus default — the plain rectangle, used when `is a` is omitted).
381
+
382
+ Type names in `is a X` are **case-insensitive** (`is a Actor`, `is an ACTOR`, `is an actor` all parse the same). The keywords `service`, `frontend`, `networking`, `gateway`, and `external` were removed in 0.16.0 and now emit `E_PARTICIPANT_TYPE_REMOVED`; drop the override and the participant renders as the default rectangle.
383
+
384
+ A participant *named* with a removed-type keyword (e.g. `service -> User: hi` declares a participant named "service") remains valid. The trim affects only the `is a X` declaration syntax, not name resolution.
360
385
 
361
386
  **Inference rules** — the parser infers the type (and shape) from the participant name. Only use `is a` when the name does not match or you want to override:
362
387
 
363
388
  | Inferred Type | Shape | Name Patterns (examples) |
364
389
  |--------------|-------|--------------------------|
365
- | actor | Stick figure | `User`, `Customer`, `Client`, `Admin`, `Agent`, `Person`, `Buyer`, `Seller`, `Guest`, `Visitor`, `Operator`, Alice, Bob, Charlie, `*User`, `*Actor`, `*Analyst`, `*Staff` |
366
- | service | Rounded rectangle | `*Service`, `*Svc`, `*API`, Lambda, `*Function`, `*Fn`, `*Job`, Cron, Auth, SSO, OAuth, Stripe, Twilio, S3, Vercel, Docker, K8s, Vault, KMS, IAM, LLM, GPT, Claude, `*Pipeline`, `*Engine`, and many `-er`/`-or` suffixes (Scheduler, Handler, Processor, Worker, etc.) |
367
- | database | Cylinder (vertical) | `*DB`, `Database`, `*Store`, `Storage`, `*Repo`, `SQL`, Postgres, MySQL, Mongo, Dynamo, Aurora, Spanner, Supabase, Firebase, BigQuery, Redshift, Snowflake, Cassandra, Neo4j, ClickHouse, Elastic, OpenSearch, Pinecone, Weaviate, `*Table` |
390
+ | actor | Stick figure | `User`, `Customer`, `Admin`, `Agent`, `Person`, `Buyer`, `Seller`, `Guest`, `Visitor`, `Operator`, `Developer`, Alice, Bob, Charlie, Fan, Purchaser, Reviewer, `*User`, `*Actor`, `*Analyst`, `*Staff` |
391
+ | database | Cylinder (vertical) | `*DB`, `Database`, `Datastore`, `*Store`, `Storage`, `*Repo`, `Repository`, `SQL`, Postgres, MySQL, Mongo, Dynamo, Aurora, Spanner, Supabase, Firebase, BigQuery, Redshift, Snowflake, Cassandra, Neo4j, ClickHouse, Elastic, OpenSearch, Druid, Trino, Pinecone, Weaviate, Qdrant, Milvus, Presto, `*Table` |
368
392
  | cache | Dashed cylinder | `*Cache`, Redis, Memcache, KeyDB, Dragonfly, Hazelcast, Valkey |
369
- | queue | Horizontal cylinder (pipe) | `*Queue`, `*MQ`, SQS, Kafka, RabbitMQ, `EventBus`, `*Bus`, `Topic`, `*Stream`, SNS, PubSub, NATS, Pulsar, Kinesis, EventBridge, Celery, Sidekiq, `*Channel`, `*Broker` |
370
- | networking | Hexagon | `*Router`, `*Balancer`, `Gateway`, `Proxy`, `LB`, `CDN`, `Firewall`, `WAF`, `DNS`, `Ingress`, Nginx, Traefik, Envoy, Istio, Kong, Akamai, Cloudflare, `*Mesh` |
371
- | frontend | Monitor (screen + stand) | `*App`, `Application`, `Mobile`, iOS, Android, `Web`, `Browser`, `Frontend`, `*UI`, `Dashboard`, `*CLI`, `Terminal`, React, Vue, Angular, Svelte, NextJS, Electron, Tauri, `*Widget`, `Portal`, `*Console`, SPA, PWA |
372
- | gateway | Rectangle (same as default) | matched via `is a gateway` only |
373
- | external | Dashed rectangle | `External`, `*Ext`, `ThirdParty`, `*3P`, `Vendor`, `Webhook`, `Upstream`, `Downstream`, `Callback`, AWS, GCP, Azure |
393
+ | queue | Horizontal cylinder (pipe) | `*Queue`, `*MQ`, SQS, Kafka, RabbitMQ, `EventBus`, `MessageBus`, `*Bus`, `Topic`, `*Stream`, SNS, PubSub, `*Broker`, NATS, Pulsar, Kinesis, EventBridge, CloudEvents, Celery, Sidekiq, EventHub, `*Channel` |
374
394
  | default | Rectangle | Everything else (no `is a` needed) |
375
395
 
376
396
  **Inference handles it (skip `is a`):**
377
397
  ```
378
- AuthService // service (matches *Service)
379
398
  PostgresDB // database (matches *DB)
380
399
  Redis // cache (exact match)
381
400
  User // actor (exact match)
382
401
  Kafka // queue (exact match)
383
- API Gateway // networking (matches Gateway)
384
- WebApp // frontend (matches *App)
385
- Stripe // service (exact match)
386
402
  ```
387
403
 
388
404
  **Inference would miss (use `is a`):**
389
405
  ```
390
- Payments is a service // "Payments" matches no rule
391
- Vault is a database // "Vault" infers as service, but you want database
406
+ Vault is a database // "Vault" matches no rule, but you want database
392
407
  Notifications is a queue // "Notifications" matches no rule
393
- Analytics is a frontend // "Analytics" matches no rule
394
408
  ```
395
409
 
410
+ Names that previously inferred to a removed type — `AuthService`, `WebApp`, `Cloudflare`, `API Gateway`, `Stripe`, `Webhook` — now fall through to default (plain rectangle). That is the intended outcome of the trim: the visual differentiation is gone because the underlying distinction did not pull its weight.
411
+
396
412
  ### 2.2 Participant Groups
397
413
 
398
414
  ```
@@ -644,7 +660,7 @@ flowchart [Title]
644
660
  | Subroutine | `[[Label]]` | `[[Validate]]` |
645
661
  | Document | `[Label~]` | `[Report~]` |
646
662
 
647
- - Color suffix: `(Start(green))`
663
+ - Node coloring: use tags (§1.3) — flowchart nodes have no color suffix
648
664
 
649
665
  ### 4.3 Arrows
650
666
 
@@ -652,8 +668,6 @@ flowchart [Title]
652
668
  |------|--------|
653
669
  | Unlabeled | `->` |
654
670
  | Labeled | `-label->` |
655
- | Colored | `-(color)->` |
656
- | Labeled + colored | `-label(color)->` |
657
671
 
658
672
  - Color inference: `yes/success/ok/true` infers green; `no/fail/error/false` infers red
659
673
 
@@ -695,7 +709,7 @@ state [Title]
695
709
 
696
710
  ```
697
711
  StateName
698
- StateName(color)
712
+ StateName color
699
713
  [*] // initial/final pseudostate
700
714
  ```
701
715
 
@@ -705,13 +719,12 @@ StateName(color)
705
719
  |------|--------|
706
720
  | Unlabeled | `Idle -> Active` |
707
721
  | Labeled | `Idle -submit-> Processing` |
708
- | Colored | `Idle -(blue)-> Active` |
709
722
 
710
723
  ### 5.4 Groups
711
724
 
712
725
  ```
713
726
  [Group Name]
714
- [Group Name](color)
727
+ [Group Name] color
715
728
  ```
716
729
 
717
730
  ### 5.5 Options
@@ -742,7 +755,7 @@ CEO
742
755
  CFO
743
756
  ```
744
757
 
745
- - Color suffix: `Alice(blue)`
758
+ - Node coloring: per-node indented metadata `\n color: blue` (deferred to a follow-up spec; tag groups inside org also work)
746
759
  - Pipe metadata: `Alice | role: CEO, t: Exec`
747
760
 
748
761
  ### 6.3 Metadata (Indented, Colon REQUIRED)
@@ -863,7 +876,7 @@ er [Title]
863
876
 
864
877
  ```
865
878
  users
866
- users(blue)
879
+ users blue
867
880
  users | domain: Core
868
881
  ```
869
882
 
@@ -986,7 +999,7 @@ Columns represent workflow stages and must flow left-to-right from least-done to
986
999
 
987
1000
  ```
988
1001
  [Column Name]
989
- [Column Name](color) | wip: 3
1002
+ [Column Name] color | wip: 3
990
1003
  ```
991
1004
 
992
1005
  ### 10.3 Cards (Indented Under Columns)
@@ -1118,14 +1131,14 @@ Top-level directive (not nested under `holiday`).
1118
1131
 
1119
1132
  **Flat form:**
1120
1133
  ```
1121
- era 2026-04-06 -> 2026-04-10 Conference (purple)
1134
+ era 2026-04-06 -> 2026-04-10 Conference purple
1122
1135
  ```
1123
1136
 
1124
1137
  **Block form:**
1125
1138
  ```
1126
1139
  era
1127
- 2026-04-06 -> 2026-04-10 Conference (purple)
1128
- 2026-06-01 -> 2026-06-05 Sprint Review (blue)
1140
+ 2026-04-06 -> 2026-04-10 Conference purple
1141
+ 2026-06-01 -> 2026-06-05 Sprint Review blue
1129
1142
  ```
1130
1143
 
1131
1144
  ### 12.6 Markers
@@ -1139,7 +1152,7 @@ marker 2026-03-27 Board Review
1139
1152
  ```
1140
1153
  marker
1141
1154
  2026-03-27 Board Review
1142
- 2026-06-15 Release (green)
1155
+ 2026-06-15 Release green
1143
1156
  ```
1144
1157
 
1145
1158
  ### 12.7 Groups (Swimlanes)
@@ -1322,21 +1335,21 @@ era 1716 -> 1718 Nassau Republic
1322
1335
  ```
1323
1336
  era
1324
1337
  1716 -> 1718 Nassau Republic
1325
- 1718 -> 1720 Woodes Rogers Era (orange)
1338
+ 1718 -> 1720 Woodes Rogers Era orange
1326
1339
  ```
1327
1340
 
1328
1341
  ### 14.4 Markers
1329
1342
 
1330
1343
  **Flat form:**
1331
1344
  ```
1332
- marker 1718-07 Woodes Rogers arrives (orange)
1345
+ marker 1718-07 Woodes Rogers arrives orange
1333
1346
  ```
1334
1347
 
1335
1348
  **Block form:**
1336
1349
  ```
1337
1350
  marker
1338
- 1718-07 Woodes Rogers arrives (orange)
1339
- 1720-01 End of Golden Age (red)
1351
+ 1718-07 Woodes Rogers arrives orange
1352
+ 1720-01 End of Golden Age red
1340
1353
  ```
1341
1354
 
1342
1355
  ### 14.5 Groups
@@ -1365,11 +1378,11 @@ Q1 400, 700, 300, 500 ⚠ tolerated; use spaces
1365
1378
 
1366
1379
  ```
1367
1380
  series ✅ preferred
1368
- Cloud Platform (blue)
1369
- Legacy Suite (red)
1370
- Mobile App (green)
1381
+ Cloud Platform blue
1382
+ Legacy Suite red
1383
+ Mobile App green
1371
1384
 
1372
- series Cloud (blue), Legacy (red) ⚠ tolerated; prefer the block
1385
+ series Cloud blue, Legacy red ⚠ tolerated; prefer the block
1373
1386
  ```
1374
1387
 
1375
1388
  Parsers accept either form. The rules above are authoring guidance.
@@ -1381,8 +1394,8 @@ Parsers accept either form. The rules above are authoring guidance.
1381
1394
  **Series** — follows Rule B (prefer the indented block):
1382
1395
  ```
1383
1396
  series
1384
- Cloud Platform (blue)
1385
- Legacy Suite (red)
1397
+ Cloud Platform blue
1398
+ Legacy Suite red
1386
1399
  ```
1387
1400
 
1388
1401
  Short one-line form is tolerated: `series Revenue` or `series A B`.
@@ -1391,7 +1404,7 @@ Short one-line form is tolerated: `series Revenue` or `series A B`.
1391
1404
  ```
1392
1405
  Label 100
1393
1406
  Label 100 200 300
1394
- Label(color) 100
1407
+ Label color 100 // trailing color before numeric values
1395
1408
  Q1 400 700 300 500
1396
1409
  ```
1397
1410
 
@@ -1425,7 +1438,7 @@ Each chart honors the subset of flags that has a renderable atom on it:
1425
1438
 
1426
1439
  **Eras (line/area only):**
1427
1440
  ```
1428
- era Day 1 -> Day 3 Rough Seas (red)
1441
+ era Day 1 -> Day 3 Rough Seas red
1429
1442
  ```
1430
1443
 
1431
1444
  ### 15.2 Scatter / Bubble Charts
@@ -1438,7 +1451,7 @@ Name x y size
1438
1451
 
1439
1452
  **Categories:**
1440
1453
  ```
1441
- [Caribbean](red)
1454
+ [Caribbean] red
1442
1455
  Blackbeard 90 8500
1443
1456
  ```
1444
1457
 
@@ -1477,8 +1490,8 @@ x-label Distance
1477
1490
  y-label Height
1478
1491
  x 0 to 250
1479
1492
 
1480
- 15 degrees(blue): -0.001*x^2 + 0.27*x
1481
- 45 degrees(red): -0.003*x^2 + 0.75*x
1493
+ 15 degrees blue: -0.001*x^2 + 0.27*x
1494
+ 45 degrees red: -0.003*x^2 + 0.75*x
1482
1495
  ```
1483
1496
 
1484
1497
  The colon between name and expression is **required** — both sides can contain spaces, so colon is the unambiguous delimiter.
@@ -1490,8 +1503,8 @@ The colon between name and expression is **required** — both sides can contain
1490
1503
 
1491
1504
  **Tree structure (indented, space-separated):**
1492
1505
  ```
1493
- Sugar Plantations(green)
1494
- Tortuga Distillery(orange) 3000
1506
+ Sugar Plantations green
1507
+ Tortuga Distillery orange 3000
1495
1508
  Nassau Distillery 2500
1496
1509
  ```
1497
1510
 
@@ -1544,7 +1557,7 @@ Roberts 12 52
1544
1557
  ```
1545
1558
  - Data rows: `Label value1 value2` — follows §15 Rule A (space-separated; commas between values tolerated for back-compat but not idiomatic)
1546
1559
  - Thousands commas within values supported (e.g., `1,000`)
1547
- - Color annotations: `Label (color) value1 value2`
1560
+ - Color annotations: `Label color value1 value2` (trailing color word before numeric values)
1548
1561
  - Minimum 2 periods required
1549
1562
 
1550
1563
  ### 16.2 Wordcloud
@@ -1567,7 +1580,7 @@ navigation 88
1567
1580
  ```
1568
1581
  arc Pirate Alliances
1569
1582
 
1570
- [Caribbean](red)
1583
+ [Caribbean] red
1571
1584
  Blackbeard -> Bonnet 8
1572
1585
  Blackbeard -> Vane 5
1573
1586
 
@@ -1582,15 +1595,15 @@ order group
1582
1595
  ```
1583
1596
  venn Skill Overlap
1584
1597
 
1585
- Swordsmanship(red) as sw
1586
- Navigation(blue) as nav
1587
- Leadership(green) as lead
1598
+ Swordsmanship red as sw
1599
+ Navigation blue as nav
1600
+ Leadership green as lead
1588
1601
 
1589
1602
  sw + nav Sea Raiders
1590
1603
  sw + nav + lead Legendary Pirates
1591
1604
  ```
1592
1605
 
1593
- - Set declaration: `Name(color) as <alias>` — uses the universal alias syntax (§2A)
1606
+ - Set declaration: `Name [color] as <alias>` — color is an optional trailing token BEFORE `as` (universal alias syntax, §2A)
1594
1607
  - Intersections: `Set1 + Set2 Label` — label follows the last set reference (no colon)
1595
1608
  - Legacy `Name(color) alias X` emits `E_VENN_ALIAS_KEYWORD_REMOVED` per TD-18
1596
1609
 
@@ -1601,10 +1614,10 @@ quadrant Crew Assessment
1601
1614
  x-label Low Skill, High Skill
1602
1615
  y-label Low Loyalty, High Loyalty
1603
1616
 
1604
- top-right Promote (green)
1605
- top-left Train (yellow)
1606
- bottom-left Maroon (red)
1607
- bottom-right Watch Closely (purple)
1617
+ top-right Promote green
1618
+ top-left Train yellow
1619
+ bottom-left Maroon red
1620
+ bottom-right Watch Closely purple
1608
1621
 
1609
1622
  Quartermaster 0.9 0.95
1610
1623
  Navigator 0.85 0.8
@@ -27,7 +27,7 @@ tag: Role
27
27
  Gateway(blue)
28
28
  Storage(green)
29
29
 
30
- API is a service | role: Gateway
30
+ API | role: Gateway
31
31
  DB is a database | role: Storage
32
32
  ```
33
33
 
@@ -2,9 +2,9 @@ area Memory Usage Over Time
2
2
  x-label Hour
3
3
  y-label GB
4
4
 
5
- era 12am -> 9am Night (blue)
6
- era 9am -> 6pm Day (green)
7
- era 6pm -> 11pm Evening (purple)
5
+ era 12am -> 9am Night blue
6
+ era 9am -> 6pm Day green
7
+ era 6pm -> 11pm Evening purple
8
8
 
9
9
  12am 2.1
10
10
  3am 1.8
@@ -3,11 +3,11 @@ x-label Month
3
3
  y-label Tickets
4
4
 
5
5
  series
6
- Critical (red)
7
- High (orange)
8
- Medium (yellow)
9
- Low (green)
10
- Info (blue)
6
+ Critical red
7
+ High orange
8
+ Medium yellow
9
+ Low green
10
+ Info blue
11
11
 
12
12
  January 8 24 45 62 31
13
13
  February 12 19 51 58 28
@@ -1,7 +1,7 @@
1
1
  boxes-and-lines E-Commerce Platform
2
2
 
3
- tag Team t Backend(blue), Frontend(green), Platform(purple)
4
- tag Priority p High(red), Medium(orange), Low(gray)
3
+ tag Team t Backend blue, Frontend green, Platform purple
4
+ tag Priority p High red, Medium orange, Low gray
5
5
 
6
6
  active-tag Team
7
7
  hide priority:Low
@@ -1,16 +1,16 @@
1
1
  c4 Online Bookstore — C4 Architecture
2
2
 
3
3
  tag Technology as tech
4
- React(blue)
5
- Node(green)
6
- Python(orange)
7
- PostgreSQL(purple)
4
+ React blue
5
+ Node green
6
+ Python orange
7
+ PostgreSQL purple
8
8
 
9
9
  tag Team as t
10
- Frontend(blue)
11
- Backend(green)
12
- Platform(teal)
13
- Data(purple)
10
+ Frontend blue
11
+ Backend green
12
+ Platform teal
13
+ Data purple
14
14
 
15
15
  Customer is a person | t: Frontend
16
16
  description: Browses and purchases books online
@@ -4,7 +4,7 @@ Drawable [interface]
4
4
  + draw(): void
5
5
  + resize(w: number, h: number): void
6
6
 
7
- Shape implements Drawable [abstract] (purple)
7
+ Shape implements Drawable [abstract] purple
8
8
  # x: number
9
9
  # y: number
10
10
  + area(): number
@@ -20,7 +20,7 @@ Rectangle extends Shape
20
20
  - height: number
21
21
  + getDiagonal(): number
22
22
 
23
- Color [enum] (yellow)
23
+ Color [enum] yellow
24
24
  Red
25
25
  Green
26
26
  Blue
@@ -1,8 +1,8 @@
1
1
  doughnut Cloud Spending by Service
2
2
 
3
- Compute (blue) 34
4
- Storage (cyan) 22
5
- Database (green) 18
6
- Networking (orange) 12
7
- AI/ML (purple) 8
8
- Other (gray) 6
3
+ Compute blue 34
4
+ Storage cyan 22
5
+ Database green 18
6
+ Networking orange 12
7
+ AI/ML purple 8
8
+ Other gray 6
@@ -1,5 +1,5 @@
1
1
  flowchart Color Demo
2
2
 
3
- (Start(green)) -> [Parse Input] -> <Valid?(blue)>
4
- -yes(green)-> [Process(teal)] -> (Success(green))
5
- -no(red)-> [Error Handler(red)] -> /Log Error(orange)/ -> (Failure(red))
3
+ (Start) -> [Parse Input] -> <Valid?>
4
+ -yes-> [Process] -> (Success)
5
+ -no-> [Error Handler] -> /Log Error/ -> (Failure)
@@ -3,6 +3,6 @@ x-label x
3
3
  y-label f(x)
4
4
 
5
5
  x -6 to 6
6
- f(x) (blue) sin(x)
7
- g(x) (red) x^2 / 10
8
- h(x) (green) cos(x) * 2
6
+ f(x) blue: sin(x)
7
+ g(x) red: x^2 / 10
8
+ h(x) green: cos(x) * 2