@diagrammo/dgmo 0.94.0 → 0.96.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 (220) hide show
  1. package/README.md +1 -1
  2. package/dist/advanced.d.ts +97 -570
  3. package/dist/advanced.js +176 -352
  4. package/dist/block.d.ts +6 -0
  5. package/dist/block.js +59 -57
  6. package/dist/{calculator-BNH3GSJE.js → calculator-GIB7POFX.js} +2 -2
  7. package/dist/{chart-meta-BbjsRY7o.d.ts → chart-meta-uImk4eTn.d.ts} +1 -1
  8. package/dist/chart-meta.d.ts +2 -2
  9. package/dist/chart-meta.js +16 -16
  10. package/dist/{chart-types-Cppnp31G.d.ts → chart-types-CBVYiLqy.d.ts} +1 -5
  11. package/dist/{charts-d3-SZV2SFTM.js → charts-d3-IRP5VANE.js} +5 -5
  12. package/dist/{chunk-MLY5ALOV.js → chunk-2BYFNZVM.js} +2 -2
  13. package/dist/{chunk-OSSTOSXU.js → chunk-2M3K6GD2.js} +3 -6
  14. package/dist/{chunk-CDM6XMOT.js → chunk-34JOHSVE.js} +2 -2
  15. package/dist/chunk-35A3J4Z5.js +14 -0
  16. package/dist/{chunk-HI6R27YA.js → chunk-3W73ZP6W.js} +9 -4
  17. package/dist/{chunk-IHN6WDEY.js → chunk-4B45SNZH.js} +5 -5
  18. package/dist/{chunk-AULZD45V.js → chunk-5ARANBIE.js} +2 -2
  19. package/dist/{chunk-DDIOWNHS.js → chunk-5BG4OSWJ.js} +6 -6
  20. package/dist/{chunk-6JCTW74W.js → chunk-5G4DOOX2.js} +1 -1
  21. package/dist/{chunk-JT2BG7LM.js → chunk-5GU6C5WB.js} +3 -3
  22. package/dist/{chunk-EBIDNRSR.js → chunk-5H7SA5ZD.js} +1 -1
  23. package/dist/{chunk-CN4RDJDV.js → chunk-5LG526X7.js} +1 -1
  24. package/dist/{chunk-VDY2GR6U.js → chunk-67N26CER.js} +2 -2
  25. package/dist/{chunk-G3HZ4PGE.js → chunk-67RKJEKF.js} +6 -6
  26. package/dist/{chunk-D3K4U3ZM.js → chunk-6K2W3FH7.js} +8 -5
  27. package/dist/{chunk-C6G36F5S.js → chunk-7UWVHNPM.js} +4 -4
  28. package/dist/{chunk-FWVE373X.js → chunk-AQRSEQZV.js} +1 -1
  29. package/dist/{chunk-BQO24BDM.js → chunk-AUXUNV73.js} +1 -1
  30. package/dist/{chunk-3PP746YM.js → chunk-B2YVZ3QU.js} +1 -1
  31. package/dist/{chunk-QPQWY5RU.js → chunk-B5CEV7IR.js} +3 -3
  32. package/dist/{chunk-J7Q4AB23.js → chunk-B7BSRVNC.js} +2 -2
  33. package/dist/{chunk-IXHWS2HI.js → chunk-BD4O4D2A.js} +2 -2
  34. package/dist/{chunk-4TEPDQHJ.js → chunk-BUVLLK3D.js} +7 -7
  35. package/dist/{chunk-B25IWGDH.js → chunk-CD7VQCDL.js} +8 -8
  36. package/dist/{chunk-I37S3EZE.js → chunk-CP73WWLN.js} +371 -286
  37. package/dist/{chunk-GI5R5B3S.js → chunk-D7DGLJ7N.js} +2 -2
  38. package/dist/{chunk-3TWBMU7K.js → chunk-DKCVAQU3.js} +9 -9
  39. package/dist/{chunk-KBDMEOLI.js → chunk-DPNSDCR3.js} +1 -1
  40. package/dist/{chunk-BRGRIZQB.js → chunk-DWMQ24JR.js} +2 -2
  41. package/dist/{chunk-4XYZJTFO.js → chunk-EM5SA7NC.js} +11 -3
  42. package/dist/{chunk-AM42TLSZ.js → chunk-EMGNCG5C.js} +1 -1
  43. package/dist/{chunk-3KVUFHUJ.js → chunk-EPB3UEMD.js} +2 -2
  44. package/dist/{chunk-NXU4N5WT.js → chunk-EZ6BI5LL.js} +1 -1
  45. package/dist/{chunk-2ZW4NBYX.js → chunk-FBK32S4D.js} +1 -1
  46. package/dist/{chunk-2I4UQG7W.js → chunk-FHX373L5.js} +1 -1
  47. package/dist/{chunk-AQQUJEDN.js → chunk-FKJWZWNU.js} +1 -1
  48. package/dist/{chunk-TIIZIAGS.js → chunk-FUYEXLAN.js} +6 -13
  49. package/dist/{chunk-TASRGDYP.js → chunk-GEHK4UD5.js} +3 -3
  50. package/dist/{chunk-ZD3QCNB7.js → chunk-GLL237AP.js} +2 -2
  51. package/dist/{chunk-PGSGJLUR.js → chunk-GM2SLMQW.js} +2 -2
  52. package/dist/{chunk-NOQB4KMV.js → chunk-H7JVKUA5.js} +5 -5
  53. package/dist/{chunk-DNM3XZCK.js → chunk-H7RQG4PH.js} +2 -2
  54. package/dist/{chunk-7SXV7NUS.js → chunk-HH3DHNQA.js} +2 -2
  55. package/dist/{chunk-GWQRTA5W.js → chunk-HZX4QZGR.js} +1 -1
  56. package/dist/{chunk-KBEWVCK3.js → chunk-I2I2FKAK.js} +1 -1
  57. package/dist/{chunk-2HSHWPTO.js → chunk-I3ZRIMR7.js} +10 -10
  58. package/dist/{chunk-7IOZ6JE4.js → chunk-IKXQ6NVR.js} +7 -7
  59. package/dist/{chunk-XJQ6Z3FO.js → chunk-IQZSKWE5.js} +3 -3
  60. package/dist/{chunk-3GUEYQGL.js → chunk-ITDF3MWD.js} +3 -3
  61. package/dist/{chunk-JXGSTBW6.js → chunk-IU7XKZA6.js} +2 -2
  62. package/dist/{chunk-RITTLIDJ.js → chunk-IZFJZCF6.js} +4 -4
  63. package/dist/{chunk-DRQSB72S.js → chunk-JBAFAKGX.js} +7 -7
  64. package/dist/{chunk-VSAKEMDD.js → chunk-JCC3B2GS.js} +8 -2
  65. package/dist/{chunk-66JTY4AN.js → chunk-JRN2CRXJ.js} +1 -1
  66. package/dist/{chunk-2FDQEQID.js → chunk-K2SFH3GJ.js} +2 -2
  67. package/dist/{chunk-NM5V5EKY.js → chunk-K2WXMXI2.js} +1 -1
  68. package/dist/{chunk-XKCRKD2B.js → chunk-KDWEOT54.js} +24 -12
  69. package/dist/{chunk-PVWIBKV2.js → chunk-KQAPFIYF.js} +2 -2
  70. package/dist/{chunk-4SACN2C5.js → chunk-LGUFJ7Y2.js} +1 -1
  71. package/dist/{chunk-AYUSD4Z6.js → chunk-LRHPBWOY.js} +5 -5
  72. package/dist/{chunk-DLJJOCIT.js → chunk-M4ZUIW3J.js} +3 -3
  73. package/dist/{chunk-CIHHTS5B.js → chunk-MAYTYF5S.js} +3 -3
  74. package/dist/{chunk-5ZUZZDW5.js → chunk-MVUNMJKO.js} +46 -52
  75. package/dist/{chunk-KBHT5XEY.js → chunk-MYHR3PMH.js} +194 -35
  76. package/dist/{chunk-NBAAIRFP.js → chunk-NI4L6HEU.js} +4 -1
  77. package/dist/{chunk-A2A2I4Z4.js → chunk-O2HNVNKO.js} +2 -2
  78. package/dist/{chunk-2XMTZ5JR.js → chunk-OAZ6BIIB.js} +3 -3
  79. package/dist/{chunk-IZHGT5HD.js → chunk-OO4GUE4E.js} +3 -3
  80. package/dist/{chunk-KSZB7TIY.js → chunk-OYGJZA24.js} +8 -8
  81. package/dist/{chunk-H6BT45SN.js → chunk-P2GNNEMN.js} +1 -1
  82. package/dist/{chunk-5HAYT43L.js → chunk-P3PSLC2K.js} +22 -6
  83. package/dist/{chunk-HHVIE45A.js → chunk-P6LKX3IQ.js} +4 -4
  84. package/dist/{chunk-NMS5XSLX.js → chunk-PGD6CNWO.js} +1 -1
  85. package/dist/{chunk-NVZ7R4EK.js → chunk-PWZEJNO6.js} +3 -3
  86. package/dist/{chunk-NPDVWFAQ.js → chunk-QEU6VM4O.js} +1 -1
  87. package/dist/{chunk-UIEKW4SG.js → chunk-R5L5E3TC.js} +0 -1
  88. package/dist/{chunk-2WQ3YZMN.js → chunk-RGFVHYDP.js} +2 -2
  89. package/dist/{chunk-YQMIKX54.js → chunk-RIK6WUMO.js} +62 -29
  90. package/dist/{chunk-BH2SF4TT.js → chunk-RTRORHSP.js} +1 -1
  91. package/dist/{chunk-4SP6OUO7.js → chunk-RVOSA4RR.js} +845 -193
  92. package/dist/{chunk-LKZCUFOW.js → chunk-SCYVGPLI.js} +2 -2
  93. package/dist/{chunk-XIUGSUE4.js → chunk-SIABEREK.js} +6 -2
  94. package/dist/{chunk-P7TRFL4P.js → chunk-SQBCNEJB.js} +4 -1
  95. package/dist/{chunk-3ZP3QC47.js → chunk-THTYCJGF.js} +2 -2
  96. package/dist/{chunk-4EX4OKGZ.js → chunk-TIPNNOZC.js} +5 -5
  97. package/dist/{chunk-UZ7EZW3B.js → chunk-TO53KK2P.js} +6 -1
  98. package/dist/{chunk-2MS623GW.js → chunk-TPCP2UOI.js} +3 -3
  99. package/dist/{chunk-Y3SIQN4J.js → chunk-TUOZ6AXC.js} +2 -2
  100. package/dist/{chunk-KRPLP5LP.js → chunk-U6N547QA.js} +1 -1
  101. package/dist/{chunk-RESEJSCV.js → chunk-VJ7NLYFE.js} +2 -2
  102. package/dist/{chunk-UXNA2H2V.js → chunk-VLI6AWS3.js} +2 -2
  103. package/dist/{chunk-TDAGJJPZ.js → chunk-VNAPEZX2.js} +1 -1
  104. package/dist/{chunk-EBVVMUAA.js → chunk-VVTCUIPN.js} +1 -1
  105. package/dist/{chunk-FVTYJUXR.js → chunk-W5MMPPGX.js} +2 -2
  106. package/dist/{chunk-BQMHJ6OW.js → chunk-WGNP5ND2.js} +20 -12
  107. package/dist/{chunk-5OTA2PUH.js → chunk-WLGOIMTI.js} +2 -2
  108. package/dist/{chunk-IGJEKO2P.js → chunk-WTPS73RM.js} +4 -4
  109. package/dist/{chunk-R6EGUTIV.js → chunk-YFIUABSF.js} +2 -2
  110. package/dist/{chunk-7PJBJ2DU.js → chunk-YSGOXZBB.js} +1 -1
  111. package/dist/{chunk-ZECJ7Q6C.js → chunk-YVIPJGFG.js} +2 -2
  112. package/dist/{chunk-5KKZXA44.js → chunk-ZBOIYC2G.js} +4 -2
  113. package/dist/{chunk-RBVFNUAL.js → chunk-ZOKD5F7M.js} +2 -2
  114. package/dist/{collapse-BSPH3BFM.js → collapse-6X5S2S3G.js} +2 -1
  115. package/dist/completion-registry.js +6 -37
  116. package/dist/copy-image.d.ts +34 -0
  117. package/dist/copy-image.js +96 -0
  118. package/dist/countdown.js +1 -1
  119. package/dist/dgmo-router-EPBQKQW2.js +100 -0
  120. package/dist/{dimensions-DS6FWLRY.js → dimensions-DBCRBZIU.js} +4 -4
  121. package/dist/editor.js +2 -7
  122. package/dist/{flowchart-parser-NZXASOZG.js → flowchart-parser-SM5LHF2D.js} +4 -4
  123. package/dist/{flowchart-renderer-PTCRIANF.js → flowchart-renderer-PPS2GTTD.js} +10 -10
  124. package/dist/highlight.js +3 -8
  125. package/dist/index.d.ts +42 -6
  126. package/dist/index.js +62 -57
  127. package/dist/{layout-MXHR3P35.js → layout-3J72UULM.js} +3 -3
  128. package/dist/{layout-U3AH6M7J.js → layout-AF4KA5B2.js} +4 -4
  129. package/dist/{layout-IT4ZTV6C.js → layout-FCFUVCRI.js} +7 -7
  130. package/dist/{layout-KV27UW25.js → layout-H2KP5A6M.js} +1 -1
  131. package/dist/{layout-ND26WVX2.js → layout-IXQNVRBE.js} +3 -3
  132. package/dist/{layout-ISSBWBH7.js → layout-KELSNWBD.js} +7 -7
  133. package/dist/{layout-JTIRCKAW.js → layout-LNVIH45F.js} +3 -3
  134. package/dist/{layout-VC3MXRB4.js → layout-MPSH3YWE.js} +7 -7
  135. package/dist/{layout-HFBK5UEG.js → layout-PPIVGJXD.js} +2 -2
  136. package/dist/{layout-RH3N46HP.js → layout-R6G4MEO3.js} +4 -3
  137. package/dist/{layout-search-BBX2BMEF.js → layout-search-C2TYUH4L.js} +5 -5
  138. package/dist/{parser-BT4NI6JY.js → parser-2AXU2MHJ.js} +3 -3
  139. package/dist/{parser-3QIFY5IN.js → parser-4BOP77CD.js} +2 -2
  140. package/dist/{parser-TAYRTCPR.js → parser-4GHAYZKZ.js} +5 -5
  141. package/dist/{parser-LTRQASGB.js → parser-5HQPPVHJ.js} +3 -3
  142. package/dist/{parser-EAQPZX2B.js → parser-5RUD4A3X.js} +3 -3
  143. package/dist/{parser-BJ7RJNUM.js → parser-6WURFLOB.js} +3 -3
  144. package/dist/{parser-R3LPEQIT.js → parser-722KLLAQ.js} +4 -4
  145. package/dist/{parser-KMKVFET2.js → parser-B7SCN7FG.js} +2 -2
  146. package/dist/{parser-TUAEX6ML.js → parser-BNRX35NT.js} +3 -3
  147. package/dist/{parser-NL73FSFI.js → parser-BPYHIG24.js} +3 -3
  148. package/dist/{parser-3LT3ZUUC.js → parser-CRJYLOHA.js} +2 -2
  149. package/dist/{parser-NUU3DVW4.js → parser-DGLKH4NT.js} +2 -2
  150. package/dist/{parser-5UZV32ZI.js → parser-DRUGM3R6.js} +2 -2
  151. package/dist/{parser-KLCSFQ3J.js → parser-DWV2CYBS.js} +3 -3
  152. package/dist/{parser-2IKPQVKX.js → parser-F3JJNIFC.js} +3 -3
  153. package/dist/{parser-EFF22GYO.js → parser-F75WNYMK.js} +3 -3
  154. package/dist/{parser-RTWPFKXG.js → parser-GBQY3WOZ.js} +3 -3
  155. package/dist/{parser-F7NDRPMA.js → parser-GM5B2EPW.js} +3 -3
  156. package/dist/{parser-K2DI26SC.js → parser-H6HT2WFQ.js} +2 -2
  157. package/dist/{parser-PEZ7RN43.js → parser-HM6FEX5K.js} +3 -3
  158. package/dist/{parser-YG625J5H.js → parser-L7SI3PW4.js} +4 -4
  159. package/dist/{parser-GMQJISZ6.js → parser-LUJX7AXO.js} +2 -2
  160. package/dist/{parser-A3AN76RQ.js → parser-MWINQNQW.js} +3 -3
  161. package/dist/{parser-KJPPUN4D.js → parser-OHBBDCG4.js} +2 -2
  162. package/dist/{parser-4RFY7D52.js → parser-QWTECQEC.js} +5 -5
  163. package/dist/{parser-4TBSWULQ.js → parser-TTGZYLYD.js} +3 -3
  164. package/dist/{parser-6TDWUKM5.js → parser-UHKROC7Z.js} +3 -3
  165. package/dist/{parser-H5OODY5N.js → parser-W6NX3AIV.js} +3 -3
  166. package/dist/{parser-GDLKUBTO.js → parser-WIKXZP4X.js} +2 -2
  167. package/dist/{parser-4Y6PODW6.js → parser-XEJP37GQ.js} +3 -3
  168. package/dist/{parser-RCIEKN7Y.js → parser-Y7QXD2UR.js} +2 -2
  169. package/dist/{parser-7QKQ4P4P.js → parser-ZV756RMP.js} +5 -5
  170. package/dist/{parser-KKF6Y5MM.js → parser-ZWWQZ4XZ.js} +4 -3
  171. package/dist/{redraw-AHW7EUUF.js → redraw-BZ4GI6IC.js} +6 -4
  172. package/dist/{redraw-STZ4WJAI.js → redraw-LEOXS7C6.js} +3 -3
  173. package/dist/{renderer-J3GPDK73.js → renderer-2MCV75JQ.js} +12 -12
  174. package/dist/{renderer-TINHO2IO.js → renderer-2V2XY2V7.js} +4 -4
  175. package/dist/{renderer-PHLCYVSN.js → renderer-5AEDVLAA.js} +8 -7
  176. package/dist/{renderer-W4MUMXJE.js → renderer-5GP7YUS4.js} +3 -3
  177. package/dist/{renderer-FMTLSOCX.js → renderer-66NCRXSC.js} +6 -6
  178. package/dist/{renderer-AM7P4LN7.js → renderer-6HU44IGJ.js} +4 -4
  179. package/dist/{renderer-JJ4QW3SK.js → renderer-7C76HP5W.js} +6 -6
  180. package/dist/{renderer-O6RP52CQ.js → renderer-7RAMBMTH.js} +6 -6
  181. package/dist/{renderer-M5DUMITP.js → renderer-BYLQ37T2.js} +8 -8
  182. package/dist/{renderer-7OGGV327.js → renderer-CVCCW7UT.js} +4 -4
  183. package/dist/{renderer-QTPWRRJ7.js → renderer-D6EH5UQ6.js} +6 -6
  184. package/dist/renderer-E3334XLT.js +84 -0
  185. package/dist/{renderer-IXBOT6DU.js → renderer-F7YGMEGQ.js} +2 -2
  186. package/dist/{renderer-XCLARXCK.js → renderer-GKY55M4Z.js} +5 -5
  187. package/dist/{renderer-KJ3V5BYP.js → renderer-LFZKG2GR.js} +5 -5
  188. package/dist/{renderer-2LYX6NHN.js → renderer-LJPUCG3U.js} +5 -5
  189. package/dist/{renderer-DAZWHNLI.js → renderer-MGF2NNGG.js} +3 -3
  190. package/dist/{renderer-HX6ICPDX.js → renderer-MVBAQP3M.js} +4 -4
  191. package/dist/{renderer-XOWDERU2.js → renderer-MZIWP55B.js} +5 -5
  192. package/dist/{renderer-MWZC7TMD.js → renderer-N6PM5CSG.js} +7 -7
  193. package/dist/{renderer-ISQJ2ELA.js → renderer-N75E3UVY.js} +5 -5
  194. package/dist/{renderer-53B523PM.js → renderer-ONENGXFQ.js} +7 -7
  195. package/dist/{renderer-RUSQJFFC.js → renderer-PEJF6R2I.js} +2 -2
  196. package/dist/{renderer-36446HSH.js → renderer-QZJZIAT3.js} +2 -2
  197. package/dist/{renderer-UTEEJDGB.js → renderer-SYRH3B62.js} +6 -6
  198. package/dist/{renderer-LNP23NSM.js → renderer-TS5NHOQD.js} +6 -6
  199. package/dist/{renderer-J7ZSTJUE.js → renderer-VNJOZPSH.js} +7 -7
  200. package/dist/{renderer-OUDHH5MV.js → renderer-VNUDN6F5.js} +12 -12
  201. package/dist/{renderer-JYHA6R2D.js → renderer-VUXAAGUG.js} +5 -5
  202. package/dist/{renderer-BXD5KVSR.js → renderer-YJVQT7QG.js} +6 -6
  203. package/dist/{renderer-radial-WFUX3Z3C.js → renderer-radial-4R7AKETK.js} +5 -5
  204. package/dist/{state-parser-KPVW5CRI.js → state-parser-EQBBEKHR.js} +5 -5
  205. package/dist/{state-renderer-ZVEI265C.js → state-renderer-SOGZ2CNN.js} +12 -12
  206. package/dist/{themes-DzIH3Hjv.d.ts → themes-CbJL3w8L.d.ts} +1 -1
  207. package/docs/ai-integration.md +5 -6
  208. package/docs/language-reference.md +69 -105
  209. package/gallery/fixtures/whiteboard.dgmo +1 -0
  210. package/package.json +5 -1
  211. package/dist/chunk-6BQSDF77.js +0 -734
  212. package/dist/chunk-NWSPPGIE.js +0 -60
  213. package/dist/chunk-VBMRZCMQ.js +0 -1465
  214. package/dist/chunk-WZBZXZ6T.js +0 -636
  215. package/dist/dgmo-router-E5O7RJSW.js +0 -101
  216. package/dist/layout-D4L44NRG.js +0 -11
  217. package/dist/parser-YHDGKPZI.js +0 -14
  218. package/dist/renderer-4SE7R22T.js +0 -85
  219. package/dist/renderer-WPN2SXGT.js +0 -29
  220. package/gallery/fixtures/sketch.dgmo +0 -22
@@ -98,7 +98,7 @@ Valid markup is the floor, not the goal. A good diagram reads at a glance. Apply
98
98
  - **Always title it.** Every diagram gets a short title on the type-declaration line (`flowchart Checkout Flow`, `sequence Checkout`, `boxes-and-lines Service Map`) so it is self-describing — never leave the bare type keyword alone. Infer a fitting title from the request when the user gives none.
99
99
  <!-- TITLE end -->
100
100
  <!-- CATEGORIZE start -->
101
- - **Categorize and color — by default, not only when obvious.** Before drawing, find the axis that sorts the items into kinds and color by it: layer (frontend / backend / data), role (client / service / datastore), trust zone (internal / external / third-party), status (done / active / blocked), owner/team, or read-path vs write-path. Almost every diagram has such an axis — actively look for one rather than leaving everything monochrome. Express it with a **tag group**, never ad-hoc per-node colors: declare `tag <Axis> as t` (the name is a single word — `tag TrustZone as tz` — or quote a multi-word name: `tag "Trust Zone" as tz`), indent the category values (a trailing color is optional — bare values auto-pick a palette color), set `active-tag <Axis>` in the header — after the tag group and before the first element, because a type such as c4 refuses it after content — then assign each item `Node t: <Category>` (see the tag-group syntax in the per-type section below). **Bracket, block, body, event-line, family, sketch and whiteboard** take the tag group but no `active-tag` line — declare the group and stop there; on event-line, family and sketch the line would be drawn as an element. **Class, flowchart, wireframe, raci, cycle, pyramid, ring, sankey, tech-radar, venn, version-control, wordcloud, arc, bar, clock, countdown, funnel, function, goal, heatmap, line, pie, polar-area, quadrant, radar, scatter and slope** take no tag group at all — skip this rule for them. Most report the lines; cycle, pyramid, ring, sankey, venn, version-control and wordcloud read them as content, and flowchart and tech-radar drop them without a word. Only the 11 named palette colors exist, and they re-resolve per palette/theme. Color the grouping so the categories — and the boundaries between them — read at a glance. **Buckets, not name tags — never 1:1.** A tag group must have _fewer_ values than it has members: each color should bucket two or more items so the palette compresses the diagram into a few meaningful kinds (aim for ~2–4 categories, and keep distinct colors well under half the item count). If you find yourself giving nearly every item its own value, you've enumerated, not categorized — merge the singletons up a level until each color groups at least two (a `cache` and a `database` are both `datastore`; a caller and a gateway are both `client`; two microservices are both `service`). One color per item is the same visual noise as random colors — the grouping only earns its place when a color means "these belong together." Leave items uncolored only when they genuinely form a single undifferentiated kind, or the user asked for no color.
101
+ - **Categorize and color — by default, not only when obvious.** Before drawing, find the axis that sorts the items into kinds and color by it: layer (frontend / backend / data), role (client / service / datastore), trust zone (internal / external / third-party), status (done / active / blocked), owner/team, or read-path vs write-path. Almost every diagram has such an axis — actively look for one rather than leaving everything monochrome. Express it with a **tag group**, never ad-hoc per-node colors: declare `tag <Axis> as t` (the name is a single word — `tag TrustZone as tz` — or quote a multi-word name: `tag "Trust Zone" as tz`), indent the category values (a trailing color is optional — bare values auto-pick a palette color), set `active-tag <Axis>` in the header — after the tag group and before the first element, because a type such as c4 refuses it after content — then assign each item `Node t: <Category>` (see the tag-group syntax in the per-type section below). **Bracket, block, body, event-line, family and whiteboard** take the tag group but no `active-tag` line — declare the group and stop there; on event-line and family the line would be drawn as an element. **Class, flowchart, wireframe, raci, cycle, pyramid, ring, sankey, tech-radar, venn, version-control, wordcloud, arc, bar, clock, countdown, funnel, function, goal, heatmap, line, pie, polar-area, quadrant, radar, scatter and slope** take no tag group at all — skip this rule for them. Most report the lines; cycle, pyramid, ring, sankey, venn, version-control and wordcloud read them as content, and flowchart and tech-radar drop them without a word. Only the 11 named palette colors exist, and they re-resolve per palette/theme. Color the grouping so the categories — and the boundaries between them — read at a glance. **Buckets, not name tags — never 1:1.** A tag group must have _fewer_ values than it has members: each color should bucket two or more items so the palette compresses the diagram into a few meaningful kinds (aim for ~2–4 categories, and keep distinct colors well under half the item count). If you find yourself giving nearly every item its own value, you've enumerated, not categorized — merge the singletons up a level until each color groups at least two (a `cache` and a `database` are both `datastore`; a caller and a gateway are both `client`; two microservices are both `service`). One color per item is the same visual noise as random colors — the grouping only earns its place when a color means "these belong together." Leave items uncolored only when they genuinely form a single undifferentiated kind, or the user asked for no color.
102
102
  <!-- CATEGORIZE end -->
103
103
  - **Keep labels short.** A few words per node. Move detail into notes or metadata, never a full sentence inside a label.
104
104
  - **Let the defaults show.** Don't add `no-*` opt-outs unless the user asked to hide or disable something — they strip helpful labels, values, and color.
@@ -141,7 +141,6 @@ Valid markup is the floor, not the goal. A good diagram reads at a glance. Apply
141
141
  | `ring` | concentric rings of nested categories |
142
142
  | `treemap` | nested rectangles sized by value (budgets, disk usage, portfolios) |
143
143
  | `block` | author-controlled grid of nested, collapsible blocks (system / architecture layouts) |
144
- | `sketch` | GUI-first free-placement canvas: uniform shapes on a snap grid, arrows, tags (markup is app-generated) |
145
144
  | `whiteboard` | free-form infinite canvas: shapes, sticky notes, free arrows, text, images and freehand ink at pixel positions (canvas-drawn; AI writes all but ink) |
146
145
  | `goal` | single progress-toward-a-target value (`now` vs `target`) as a progress bar, thermometer, or gauge — KPIs, fundraising, quotas |
147
146
  | `countdown` | live "N days until X" that ticks every second and is accurate on every load — trip dates, launches, deadlines; the only dynamic chart type |
@@ -215,7 +214,7 @@ tag GroupName as <alias>
215
214
  - Must appear before diagram content
216
215
  - Bare shorthand is not an alias (TD-18): `tag Priority p` declares a group _named_ "Priority p" — no alias registers, so `p:` assignments silently miss. The parser warns on this shape (spaced name, no alias, alias-shaped trailing word), suggesting `tag Priority as p` or a quoted name
217
216
 
218
- **Diagram types that support tags**: the tag model is near-universal across the structural types — sequence, infra, org, c4, er, kanban, gantt, sitemap, timeline, boxes-and-lines, state (§5.7), pert, swimlane, mindmap, journey-map, event-line, treemap, map, block, sketch, bracket, family and whiteboard all accept `tag <Group> as <alias>` blocks (a whiteboard's names its colours — §24Ea). Check the per-type Options section for the exact directive set; if a type draws a tag legend, it takes tags. **Flowchart, wireframe, raci and class take no tags** — a `tag` block or `active-tag` on any of them is ignored with a warning, because what an element looks like is fixed by what it is (a flowchart's shape, a wireframe's state keywords, a class's trailing colour word) or by the roles (raci).
217
+ **Diagram types that support tags**: the tag model is near-universal across the structural types — sequence, infra, org, c4, er, kanban, gantt, sitemap, timeline, boxes-and-lines, state (§5.7), pert, swimlane, mindmap, journey-map, event-line, treemap, map, block, bracket, family and whiteboard all accept `tag <Group> as <alias>` blocks (a whiteboard's names its colours — §24Ea). Check the per-type Options section for the exact directive set; if a type draws a tag legend, it takes tags. **Flowchart, wireframe, raci and class take no tags** — a `tag` block or `active-tag` on any of them is ignored with a warning, because what an element looks like is fixed by what it is (a flowchart's shape, a wireframe's state keywords, a class's trailing colour word) or by the roles (raci).
219
218
 
220
219
  ### 1.4 Same-Line Metadata
221
220
 
@@ -285,7 +284,7 @@ Two narrow exceptions accept same-line-metadata-only color: **cycle edges** (no
285
284
  - Indented content below belongs to the group
286
285
  - **A tag value on the group line colors the group's own frame**, and cascades
287
286
  to its children: `[Backend] s: Red`. Supported on boxes-and-lines, infra, c4,
288
- state, pert, kanban, gantt, sequence, org, block and sketch. Two rules: a
287
+ state, pert, kanban, gantt, sequence, org and block. Two rules: a
289
288
  group never picks up the tag group's first-value default (an untagged group
290
289
  stays neutral grey), and a value the tag group does not recognize leaves it
291
290
  neutral rather than painting a fallback shade.
@@ -431,6 +430,25 @@ A block must have every key, hex only, text readable on its fills, and a name th
431
430
 
432
431
  **Who wins**, highest first: an explicit choice where the diagram is shown (a fence `palette=` attribute, `--palette` on the command line), then the file's palette, then the site's or app's own setting, then Slate. `theme` is retired — the mode word on the palette line does its job.
433
432
 
433
+ ### 1.11 Line Breaks in Description and Note Bodies
434
+
435
+ A line break in the source is **not** a line break in the drawing. Consecutive body lines join into one paragraph and re-wrap to fit the card, so you can break prose wherever is comfortable in the editor. Two things keep a break:
436
+
437
+ - **A blank line** starts a new paragraph, with a gap above it.
438
+ - **A trailing `\`** breaks the line without starting a new paragraph (markdown's hard break).
439
+
440
+ A `- ` line always starts its own bullet. A plain line straight after a bullet continues that bullet; a blank line returns to prose.
441
+
442
+ ```
443
+ 2026-09-28 67.10.0 deployed
444
+ *9:00 AM* \
445
+ Existing refresh code already deletes opted-out cards.
446
+ ```
447
+
448
+ Without the `\`, the time and the sentence join into one line: `9:00 AM Existing refresh code…`.
449
+
450
+ This applies to event-line descriptions, pyramid, ring and cycle descriptions, boxes-and-lines descriptions, and multi-line note bodies (sequence, flowchart, state, class, ER, journey-map, countdown).
451
+
434
452
  ---
435
453
 
436
454
  ## 2. Universal Name Handling
@@ -753,6 +771,7 @@ Content formatting:
753
771
  - Inline markdown: `**bold**`, `*italic*`, `` `code` ``
754
772
  - Links: `[text](url)` and bare URLs (auto-truncated in display)
755
773
  - The note ends where the indentation does — there is **no `end` terminator** (a bare `end` line is rejected).
774
+ - Body lines join into one paragraph — a blank line or a trailing `\` keeps a break (§1.11).
756
775
 
757
776
  ### 2.6 Structural Blocks
758
777
 
@@ -772,6 +791,7 @@ parallel label
772
791
  ```
773
792
 
774
793
  - `parallel` requires a label
794
+ - `else` is bare. A second condition is `else if <condition>`; `else <label>` is an error (`'else' does not take a label`)
775
795
  - Blocks nest via indentation
776
796
  - **No `end`/terminator keyword** — a block closes by dedenting (like multi-line notes). `end` and `activate`/`deactivate` are not dgmo syntax (a bare `end` line is rejected); activation is controlled by the `activations` option (§2.7), not per-message keywords.
777
797
  - **Tags apply to participants, not messages** — there is no per-message tag/color. Color a participant by category with `<Participant> <tagAlias>: <Value>` after declaring a `tag <Name> as <alias>` group (§1.3). Message text is just the arrow label.
@@ -783,6 +803,27 @@ parallel label
783
803
  - `collapse-notes` / `no-collapse-notes`
784
804
  - `active-tag GroupName`
785
805
 
806
+ Options go in the header. Put every option line — `active-tag` included — after the `tag` groups and before the first participant declaration, `[Group]`, divider or message. An option after any of those is an error (`Options like 'active-tag Zone' must appear before the first message or declaration`).
807
+
808
+ ```dgmo
809
+ sequence Checkout
810
+ tag Zone as z
811
+ Internal blue
812
+ External orange
813
+ active-tag Zone
814
+
815
+ Shop is a service z: Internal
816
+ Bank is a service z: External
817
+
818
+ Shop -charge-> Bank
819
+ if approved
820
+ Bank -receipt-> Shop
821
+ else if declined
822
+ Bank -decline code-> Shop
823
+ else
824
+ Bank -timeout-> Shop
825
+ ```
826
+
786
827
  ---
787
828
 
788
829
  ## 4. Infrastructure Diagrams
@@ -955,7 +996,7 @@ API Gateway
955
996
 
956
997
  <!-- TIPS start -->
957
998
 
958
- **Styling tips:** write every connection as `Source -> Target` (or a single-line chain like `(Start) -> [Collect info] -> <Eligible?>`); write each connection on its own line. Every decision `<Question?>` MUST have at least two outgoing branches — usually `-yes->`/`-no->`, but use specific labels when the choices are not binary (e.g. `-retirement->`, `-disability->`, `-survivor->`); a decision with only one branch is invalid. Begin at exactly one start terminal `(Start)` and make every path terminate at a terminal node (`(Approved)`, `(Denied)`, `(End)`). Every node MUST connect to the rest of the graph: if a node cannot be traced from the start forward to a terminal, it is invalid — remove it, never leave it floating. Flowcharts have NO tag groups, node metadata, or manual node colors — do NOT write `tag … as …`, a `s: value` suffix, or a trailing color word; node colors are assigned automatically by shape (start terminal green, end terminals red, processes blue, decisions yellow). Just pick the right shape and let color follow. Label every decision edge so branches read unambiguously; keep each node to a short action phrase and phrase every decision as a question.
999
+ **Styling tips:** write every connection as `Source -> Target` (or a single-line chain like `(Start) -> [Collect info] -> <Eligible?>`); write each connection on its own line. Every decision `<Question?>` MUST have at least two outgoing branches — usually `-yes->`/`-no->`, but use specific labels when the choices are not binary (e.g. `-retirement->`, `-disability->`, `-survivor->`); a decision with only one branch is invalid. Begin at exactly one start terminal `(Start)` and make every path terminate at a terminal node (`(Approved)`, `(Denied)`, `(End)`). Nothing points back at the start node: no arrow may end at `(Start)`, so a loop returns to a step after it (`-retry-> [Collect info]`), never to the start. Every node MUST connect to the rest of the graph: if a node cannot be traced from the start forward to a terminal, it is invalid — remove it, never leave it floating. Flowcharts have NO tag groups, node metadata, or manual node colors — do NOT write `tag … as …`, a `s: value` suffix, or a trailing color word; node colors are assigned automatically by shape (start terminal green, end terminals red, processes blue, decisions yellow). Just pick the right shape and let color follow. Label every decision edge so branches read unambiguously; keep each node to a short action phrase and phrase every decision as a question.
959
1000
 
960
1001
  <!-- TIPS end -->
961
1002
 
@@ -1020,13 +1061,16 @@ Bracket syntax only.
1020
1061
 
1021
1062
  ### 4.7 Notes (Nodes)
1022
1063
 
1023
- Attach an annotation to a node with `note <NodeId> text` (quote the id
1024
- for multi-word labels). The note renders as a folded-corner box beside
1025
- the node, expanded at rest.
1064
+ Attach an annotation to a node with `note NodeLabel text` (quote the
1065
+ label when it has more than one word). A note names the node by its
1066
+ label, without the shape's brackets: the decision `<Email exists?>` takes
1067
+ `note "Email exists?" …`, never `note <Email exists?> …`. The note renders
1068
+ as a folded-corner box beside the node, expanded at rest.
1026
1069
 
1027
1070
  ```
1028
1071
  note Validate checks the payload schema
1029
1072
  note "Read Map" the map is half-burned
1073
+ note "Email exists?" checks the users table
1030
1074
  ```
1031
1075
 
1032
1076
  Indent lines below the heading for a multi-line body (bullets + inline
@@ -2740,7 +2784,7 @@ tag Genre as g
2740
2784
  - **Date** — optional, ISO only (`YYYY`, `YYYY-MM`, `YYYY-MM-DD`, `+HH:MM` / `+HH:MM:SS`, plus `YYYY BCE`/`BC`/`CE`/`AD`), formatted for reading as the card subtitle (`2008-09-02` → `Sep 2, 2008`). No `date:` key; no `M/D/YYYY`.
2741
2785
  - **`TBD` (future events)** — write the literal `TBD` (case-insensitive) in the date slot for a **not-yet-scheduled** event: `TBD Console Port t: Engine`. Its caption reads `TBD` and it draws a **hollow dot + faded leader** (a faded shelf edge in `no-box`) so it reads as pending. To scale, its position is **inferred from its source-order dated neighbors**: a `TBD` followed by a dated event is interpolated into that gap; a **trailing** `TBD` (nothing dated after it) parks past the last real date and the spine **trails off dashed** — the open horizon. `TBD`s never trip the bad-date / out-of-order warnings.
2742
2786
  - **Tag** — trailing same-line metadata (`g: Pop`), like timeline; colors the dot, leader, and card.
2743
- - **Description** — bare indented body lines (like `pyramid`/`ring`); `- ` makes a bullet; inline markdown (`**bold**`, `*italic*`, `` `code` ``) supported.
2787
+ - **Description** — bare indented body lines (like `pyramid`/`ring`); `- ` makes a bullet; inline markdown (`**bold**`, `*italic*`, `` `code` ``) supported. Lines join into one paragraph — a blank line or a trailing `\` keeps a break (§1.11).
2744
2788
 
2745
2789
  #### Eras
2746
2790
 
@@ -3327,7 +3371,7 @@ Act red
3327
3371
 
3328
3372
  ### Descriptions
3329
3373
 
3330
- Indented lines under a node become the description. Inline markdown is supported (`**bold**`, `*italic*`, `` `code` ``, `[links](url)`), and `- item` renders as `• item`.
3374
+ Indented lines under a node become the description. Inline markdown is supported (`**bold**`, `*italic*`, `` `code` ``, `[links](url)`), and `- item` renders as `• item`. Lines join into one paragraph — a blank line or a trailing `\` keeps a break (§1.11).
3331
3375
 
3332
3376
  ```
3333
3377
  Observe
@@ -3610,7 +3654,7 @@ Physiological orange
3610
3654
 
3611
3655
  ### Descriptions
3612
3656
 
3613
- Indented lines under a layer are description text. Markdown inline formatting (`**bold**`, `*italic*`, `` `code` ``, `[links](url)`) is supported. Bullets written as `- item` render as `• item`.
3657
+ Indented lines under a layer are description text. Markdown inline formatting (`**bold**`, `*italic*`, `` `code` ``, `[links](url)`) is supported. Bullets written as `- item` render as `• item`. Lines join into one paragraph — a blank line or a trailing `\` keeps a break (§1.11).
3614
3658
 
3615
3659
  ### Directives
3616
3660
 
@@ -3679,7 +3723,7 @@ The Open Sea cyan
3679
3723
 
3680
3724
  ### Descriptions
3681
3725
 
3682
- Indented lines under a layer are description text. Markdown inline formatting is supported. Bullets written as `- item` render as `• item`. Descriptions appear in a stacked side list with colored accent bars.
3726
+ Indented lines under a layer are description text. Markdown inline formatting is supported. Bullets written as `- item` render as `• item`. Lines join into one paragraph — a blank line or a trailing `\` keeps a break (§1.11). Descriptions appear in a stacked side list with colored accent bars.
3683
3727
 
3684
3728
  ### Directives
3685
3729
 
@@ -3903,86 +3947,6 @@ In the desktop app a block diagram is interactive: click a container header to c
3903
3947
 
3904
3948
  ---
3905
3949
 
3906
- ## 24E. Sketch Diagrams
3907
-
3908
- <!-- TYPE:sketch -->
3909
-
3910
- **Beta — expect rough edges and syntax changes.**
3911
-
3912
- <!-- TIPS start -->
3913
-
3914
- **Styling tips:** Sketch is a GUI-authored format — the desktop and web canvas editors generate this markup, so hand-writing it is the exception. If you generate it anyway: keep it SMALL (sketches read best under ~15 shapes), and either omit `at:` everywhere (shapes flow into rows) or use integer half-slot coordinates with shapes **at least 3 half-slots apart** on one axis (a footprint spans 2 half-units and the mandatory gap adds 1 more, so each shape claims a 3×3 block; 2 apart overlaps). A `[Box]` may hold another `[Box]`, to **depth 2** — a third level is refused and its shapes join the box above it. Alias any shape an edge references (`as con`). Never write `size:`, `shape:`, colors, or fonts — every shape is the same plain card. In sketch, `~` dashed means secondary emphasis, NOT async. Categorize with a tag group — kind-of-thing is meaning, and meaning lives in tags. Reach for `sketch` when the drawing itself is the content; reach for `boxes-and-lines` when topology should auto-lay-out.
3915
-
3916
- <!-- TIPS end -->
3917
-
3918
- A **GUI-first constrained canvas**: uniformly-sized shapes placed freely on a snap grid, arrows between them, meaning through tags. The renderer owns all styling — authors own placement, connection, naming, and tags. Every shape has ONE universal footprint (no resizing); text always fits (shrink → smart-wrap → `…`). Pick `sketch` when the spatial arrangement is yours to decide; pick `boxes-and-lines` when topology should auto-lay-out.
3919
-
3920
- ### Declaration
3921
-
3922
- ```
3923
- sketch [Title]
3924
- ```
3925
-
3926
- ### Example
3927
-
3928
- ```
3929
- sketch Plunder Pipeline
3930
-
3931
- tag Crew
3932
- Deck
3933
- Hold
3934
-
3935
- Spyglass Feed at: 0 0, crew: Deck
3936
- -sightings-> con
3937
- Captain's Console as con at: 2 0, crew: Deck
3938
- -orders-> bq
3939
- Divvy Service as dvy at: 4 0, crew: Hold
3940
-
3941
- [Below Decks] at: 2 2, crew: Hold
3942
- Booty Queue as bq at: 0 0
3943
- ~haul~> dvy
3944
- Ship Ledger as ledger at: 2 0
3945
-
3946
- [Armory] as armory at: 0 2, collapsed
3947
- Powder Store at: 0 0
3948
- ```
3949
-
3950
- ### Shapes
3951
-
3952
- One top-level line = one shape — a **bare name** plus same-line `key: value` metadata. Every shape is the same plain card — there are no shape kinds, and a `shape:` clause is an error (`E_SKETCH_SHAPE_UNSUPPORTED`); the shape still draws, without it. Duplicate labels are legal **when aliased** (`Cache as c1` / `Cache as c2`); unaliased duplicates merge (standard dgmo semantics).
3953
-
3954
- ### Coordinates — `at: C R`
3955
-
3956
- Integer **half-slot steps** (a slot = one footprint + the mandatory gap), origin-normalized; box children are relative to the box origin. `at:` is **optional** — un-positioned shapes flow-place in rows below existing content. Hand-authored overlap auto-resolves with a warning; nothing renders broken.
3957
-
3958
- ### Lines
3959
-
3960
- Indented under the source shape, targeting an alias (or an unambiguous bare label). Six forms: `-label->` one head · `<-label->` both heads · `-label-` no heads, plus `~` dashed twins. Unlabeled headless lines are `--` / `~~`. No left-pointing arrows — write `B -> A`, never `A <- B`. A tag on the edge tail (`crew: Hold`) colors the line. Both ends must attach.
3961
-
3962
- ### Boxes
3963
-
3964
- `[Brackets]` = a **box** (labeled group frame) — the only bracket meaning in sketch. Label mandatory; one level only (no nested boxes); taggable (frame tints, cascades to children, individual overrides); bare `collapsed` folds it to a card with the collapse-bar and edges re-target the card. Interactive fold/unfold in the app; static export renders the authored state.
3965
-
3966
- ### Node Metadata
3967
-
3968
- | Key | Type | Default | Description |
3969
- | ----------- | -------------- | ----------------------- | -------------------------------------------------------- |
3970
- | `at` | `C R` integers | flow-placed | Half-slot position (origin-normalized) |
3971
- | `collapsed` | flag | — | Box only — start folded (collapse-bar) |
3972
- | `<tag>` | declared value | untagged (neutral gray) | Tag value (cascades from box; edge tails color the line) |
3973
-
3974
- ### Directives
3975
-
3976
- | Directive | Effect |
3977
- | ----------- | -------------------- |
3978
- | `no-legend` | Hide the tag legend. |
3979
-
3980
- ### Interactivity vs export
3981
-
3982
- In the desktop and web app a sketch opens in the **canvas editor** (the code pane hides behind a toggle); boxes fold/unfold interactively. Static SVG / PNG export renders the authored state — the same interactive-vs-export split the map, treemap, and block charts use.
3983
-
3984
- ---
3985
-
3986
3950
  ## 24Ea. Whiteboard Diagrams
3987
3951
 
3988
3952
  <!-- TYPE:whiteboard -->
@@ -3991,11 +3955,11 @@ In the desktop and web app a sketch opens in the **canvas editor** (the code pan
3991
3955
 
3992
3956
  <!-- TIPS start -->
3993
3957
 
3994
- **Styling tips:** Whiteboard is a canvas-first format: people draw on it, and pen strokes (`ink` lines) only ever come from drawing — never write an `ink` line. Generate the readable parts only: `rectangle`, `ellipse`, `database`, `queue` with a label, `at: X Y` (top-left, integer pixels) and `size: W H`; `arrow` with `from: X Y, to: X Y` and an optional label, or `line` the same way for a connection with no head; add `style: dashed` to an arrow or line for a tentative or optional link; `heads: both` for a two-way arrow; `bend: 40` (px, sign picks the side) to curve a link around something in its way; `text` at a point; `note` with `at: X Y` for a sticky-note comment or open question (a 160 × 99 yellow card by default; `size:` and `color:` are optional). A shape label or a note wraps to its width on its own, so never break a sentence by hand to fit; for separate lines (a heading, a list), drop the inline label and indent each line two spaces under the element line. Leave ~40px between shapes and keep boards small (under ~15 elements). Colours are palette names (red, green, blue, teal, purple, orange, yellow, cyan, gray); leave colour off for the default ink. An arrow or line end placed inside a shape or note attaches to it and is drawn to its border, so point ends at shape centres. `no-notes` hides every note when the board is shown. Reach for `whiteboard` for a loose drawing someone will scribble over; reach for `sketch` for tagged shapes on a grid, and `boxes-and-lines` when topology should auto-lay-out.
3958
+ **Styling tips:** Whiteboard is a canvas-first format: people draw on it, and pen strokes (`ink` lines) only ever come from drawing — never write an `ink` line. Generate the readable parts only: `rectangle`, `ellipse`, `database`, `queue`, `file` (a page with a wavy bottom, for a document or file) with a label, `at: X Y` (top-left, integer pixels) and `size: W H`; `arrow` with `from: X Y, to: X Y` and an optional label, or `line` the same way for a connection with no head; add `style: dashed` to an arrow or line for a tentative or optional link; `heads: both` for a two-way arrow; `bend: 40` (px, sign picks the side) to curve a link around something in its way; `text` at a point; `note` with `at: X Y` for a sticky-note comment or open question (a 160 × 99 yellow card by default; `size:` and `color:` are optional). A shape label or a note wraps to its width on its own, so never break a sentence by hand to fit; for separate lines (a heading, a list), drop the inline label and indent each line two spaces under the element line. Leave ~40px between shapes and keep boards small (under ~15 elements). Colours are palette names (red, green, blue, teal, purple, orange, yellow, cyan, gray); leave colour off for the default ink. An arrow or line end placed inside a shape or note attaches to it and is drawn to its border, so point ends at shape centres. `no-notes` hides every note when the board is shown. Reach for `whiteboard` for a loose drawing someone will scribble over; reach for `boxes-and-lines` when topology should auto-lay-out.
3995
3959
 
3996
3960
  <!-- TIPS end -->
3997
3961
 
3998
- A **free-form whiteboard** on an infinite canvas: rectangles, ellipses, databases, queues, sticky notes, free arrows and lines, text, pasted images and freehand ink, each at absolute pixel positions. Shapes are clean vector outlines; only ink looks hand-made. The export is cropped to the drawing plus a margin. Elements draw in kind bands, bottom to top: images, shapes (`rectangle`, `ellipse`, `database`, `queue`), sticky notes, arrows and lines, text, ink. A band always draws above the one before it, so a frame drawn after its contents never hides them. Inside a band, file order decides: a later line draws on top. No syntax sets the band.
3962
+ A **free-form whiteboard** on an infinite canvas: rectangles, ellipses, databases, queues, files, sticky notes, free arrows and lines, text, pasted images and freehand ink, each at absolute pixel positions. Shapes are clean vector outlines; only ink looks hand-made. The export is cropped to the drawing plus a margin. Elements draw in kind bands, bottom to top: images; shapes, sticky notes, arrows and lines (`rectangle`, `ellipse`, `database`, `queue`, `file`, `note`, `arrow`, `line`); text; ink. A band always draws above the one before it. Inside a band, file order decides: a later line draws on top, so shapes, notes and arrows stack either way — except that an arrow or line always draws just above the latest shape or note it is attached to. No syntax sets the band.
3999
3963
 
4000
3964
  ### Declaration
4001
3965
 
@@ -4060,7 +4024,7 @@ The label is optional on shapes, notes, arrows and lines. `at:` is a top-left co
4060
4024
 
4061
4025
  Arrows and lines take `style: dashed` for a dashed stroke. Solid is the default and is never written; `dashed` is the only value `style:` accepts.
4062
4026
 
4063
- An `arrow` takes `heads: both` for a head at each end. Arrows and lines take `bend: N` (whole px) to curve: the curve's middle sits `N` px to the right of travel from `from:` to `to:` (negative bends left); `0` is straight and never written. There are no elbow connectors. Shapes take `fill: solid` (filled with their colour) or `fill: outline` (hollow); the pale `tint` is the default and never written.
4027
+ An `arrow` takes `heads: both` for a head at each end. Arrows and lines take `bend: N` (whole px) to curve: the curve's middle sits `N` px to the right of travel from `from:` to `to:` (negative bends left); `0` is straight and never written. There are no elbow connectors. Shapes take `fill: solid` (filled with their colour) or `fill: outline` (hollow); the pale `tint` is the default and never written. Shapes take `label: top` or `label: middle` to place the label at the top centre or the middle; left off it is automatic — top on a rectangle that encloses another shape, note or image, middle otherwise. A top label is larger and semibold, and fits the space above the shapes inside — it shrinks and ends in `…` rather than running into them. A middle label also moves into the clear space nearest the centre rather than run into a shape overlapping its box.
4064
4028
 
4065
4029
  ### Colours
4066
4030
 
@@ -4805,16 +4769,16 @@ API description: Main gateway
4805
4769
 
4806
4770
  Some constructs _look_ universal but are scoped to specific chart types. Don't transplant them across charts.
4807
4771
 
4808
- | Construct | Scope |
4809
- | --------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
4810
- | Bare `collapsed` trailing flag (§1.8) | sequence, infra, gantt, kanban, mindmap, pert, state, c4, event-line (eras), block, sketch, wireframe. Legacy: `collapsed: true` metadata |
4811
- | Same-line / indented metadata on declarations | all chart types except flowchart, state, data charts (§1.4) |
4812
- | Trailing-keyword flag list | wireframe only (§19) |
4813
- | `progress: <N>` key | gantt only (§13) |
4814
- | `score: <N>` + `emotion: <Word>` keys | journey-map only (§22) |
4815
- | `description: <text>` shorthand for layers | pyramid, ring (§23, §24) |
4816
- | `milestone` keyword | **removed** — use `<name> 0` (§13A) |
4817
- | `\|` operator as metadata delimiter | **removed** (§1.4). Surviving uses: wireframe `{A \| B}` braces, in-arrow `A -file\|name-> B`, quoted `"Order \| Items"` |
4772
+ | Construct | Scope |
4773
+ | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
4774
+ | Bare `collapsed` trailing flag (§1.8) | sequence, infra, gantt, kanban, mindmap, pert, state, c4, event-line (eras), block, wireframe. Legacy: `collapsed: true` metadata |
4775
+ | Same-line / indented metadata on declarations | all chart types except flowchart, state, data charts (§1.4) |
4776
+ | Trailing-keyword flag list | wireframe only (§19) |
4777
+ | `progress: <N>` key | gantt only (§13) |
4778
+ | `score: <N>` + `emotion: <Word>` keys | journey-map only (§22) |
4779
+ | `description: <text>` shorthand for layers | pyramid, ring (§23, §24) |
4780
+ | `milestone` keyword | **removed** — use `<name> 0` (§13A) |
4781
+ | `\|` operator as metadata delimiter | **removed** (§1.4). Surviving uses: wireframe `{A \| B}` braces, in-arrow `A -file\|name-> B`, quoted `"Order \| Items"` |
4818
4782
 
4819
4783
  ### 26.4 Quoted Names + Aliases — Pick One
4820
4784
 
@@ -9,6 +9,7 @@ rectangle Magic link at: 60 250, size: 180 70, color: green
9
9
  arrow emails a code from: 150 95, to: 150 285, color: green
10
10
  database Users at: 420 160, size: 140 100, color: purple, fill: solid
11
11
  queue Email jobs at: 300 380, size: 200 64, color: orange
12
+ file Audit log at: 60 400, size: 140 80, color: gray
12
13
  arrow from: 150 285, to: 400 412, color: orange, bend: 50
13
14
  text keep it to ONE screen at: 62 184
14
15
  text 2FA here?? at: 560 -4, color: red
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diagrammo/dgmo",
3
- "version": "0.94.0",
3
+ "version": "0.96.0",
4
4
  "description": "DGMO diagram markup language — parser, renderer, and color system",
5
5
  "license": "MIT",
6
6
  "author": "Diagrammo LLC",
@@ -57,6 +57,10 @@
57
57
  "types": "./dist/clock.d.ts",
58
58
  "default": "./dist/clock.js"
59
59
  },
60
+ "./copy-image": {
61
+ "types": "./dist/copy-image.d.ts",
62
+ "default": "./dist/copy-image.js"
63
+ },
60
64
  "./pert": {
61
65
  "types": "./dist/pert.d.ts",
62
66
  "default": "./dist/pert.js"