@diagrammo/dgmo 0.51.0 → 0.52.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 (201) hide show
  1. package/.cursorrules +15 -19
  2. package/.github/copilot-instructions.md +15 -19
  3. package/.windsurfrules +15 -19
  4. package/SKILL.md +15 -19
  5. package/dist/advanced.d.ts +70 -42
  6. package/dist/advanced.js +115 -119
  7. package/dist/auto.js +125 -123
  8. package/dist/auto.mjs +952 -492
  9. package/dist/block.js +89 -52
  10. package/dist/{charts-d3-7E4B4IMW.js → charts-d3-MXEP6BNP.js} +7 -7
  11. package/dist/{chunk-CC4YRBWV.js → chunk-3HF5YEFJ.js} +17 -7
  12. package/dist/{chunk-5X6YQA2J.js → chunk-3HGU63UY.js} +12 -11
  13. package/dist/{chunk-4XFBQT5O.js → chunk-3LK5DNED.js} +2 -2
  14. package/dist/{chunk-IEDMFNU7.js → chunk-3QD7VP3U.js} +9 -4
  15. package/dist/{chunk-JJXGQIRV.js → chunk-3YRPZ7ZZ.js} +2 -2
  16. package/dist/{chunk-OJTXTQA2.js → chunk-44VCIPHF.js} +21 -17
  17. package/dist/{chunk-RAHVMKBG.js → chunk-4AQRFDXL.js} +2 -2
  18. package/dist/{chunk-6MNGECP2.js → chunk-4IHAV6O7.js} +2 -2
  19. package/dist/{chunk-ENRS56GC.js → chunk-4UNQ6X24.js} +10 -7
  20. package/dist/{chunk-JM4LEPY3.js → chunk-4YFKQ5WT.js} +6 -3
  21. package/dist/{chunk-U5SI5NIM.js → chunk-5223KXFD.js} +39 -22
  22. package/dist/{chunk-NI3XQBPB.js → chunk-5BHJZH62.js} +3 -3
  23. package/dist/{chunk-QYTPPDAO.js → chunk-5HILBT7X.js} +2 -2
  24. package/dist/{chunk-I2QZFCS2.js → chunk-5NGAO4QK.js} +4 -4
  25. package/dist/{chunk-BGP54HVR.js → chunk-5RP7JRVP.js} +4 -4
  26. package/dist/{chunk-IE477RQZ.js → chunk-5SEVICBT.js} +5 -5
  27. package/dist/{chunk-OZPBJM5Q.js → chunk-6EJITS44.js} +8 -5
  28. package/dist/{chunk-F3FYUFUH.js → chunk-6HQH6JZE.js} +12 -11
  29. package/dist/{chunk-X7EC3L2H.js → chunk-6LBQ7ELG.js} +14 -15
  30. package/dist/{chunk-5WPNFSXP.js → chunk-75G3Q4DK.js} +3 -3
  31. package/dist/{chunk-BYJBIALT.js → chunk-77FGAVZC.js} +10 -7
  32. package/dist/{chunk-2EQMXBBQ.js → chunk-7BIZCTAX.js} +2 -2
  33. package/dist/{chunk-B63YB7X3.js → chunk-7KINELPI.js} +110 -48
  34. package/dist/{chunk-AB7INMR5.js → chunk-7QE3XMRK.js} +15 -14
  35. package/dist/{chunk-IUJODQKX.js → chunk-AAXZDUOV.js} +15 -14
  36. package/dist/{chunk-2UJSV2VT.js → chunk-AL672HNE.js} +3 -3
  37. package/dist/{chunk-WQLMU7VG.js → chunk-ARGMQ3H4.js} +2 -2
  38. package/dist/{chunk-OU7HLO7I.js → chunk-AUIM2NVH.js} +3 -3
  39. package/dist/{chunk-RXKTSFDL.js → chunk-BKVOYV6I.js} +24 -32
  40. package/dist/{chunk-TK2VQQX2.js → chunk-BPIZNB5O.js} +14 -12
  41. package/dist/{chunk-3LV2NCB6.js → chunk-BPY242XU.js} +6 -4
  42. package/dist/{chunk-LV4BETUU.js → chunk-BRENJ2BQ.js} +32 -2
  43. package/dist/{chunk-Y6GBQTBK.js → chunk-CCNDLW7Z.js} +41 -19
  44. package/dist/{chunk-EXOQP75F.js → chunk-CIRFIL4M.js} +47 -27
  45. package/dist/{chunk-RBDIYLA5.js → chunk-DAOFNU6J.js} +17 -1
  46. package/dist/{chunk-4VWJ4LW2.js → chunk-DYWQFQJP.js} +44 -34
  47. package/dist/{chunk-QZPEGJOM.js → chunk-EMLPOL77.js} +15 -8
  48. package/dist/{chunk-IUO34HKW.js → chunk-FHGVORFO.js} +26 -22
  49. package/dist/{chunk-6H7O2OPM.js → chunk-FQ7HTV52.js} +4 -2
  50. package/dist/{chunk-7DYOELRK.js → chunk-FQMUHRVC.js} +69 -30
  51. package/dist/{chunk-AFIEPDLX.js → chunk-FT3ZYWET.js} +14 -3
  52. package/dist/{chunk-ND76YJCN.js → chunk-FUPF2UYQ.js} +35 -11
  53. package/dist/{chunk-6NFYEQDX.js → chunk-FY5MSZAP.js} +15 -3
  54. package/dist/{chunk-IEWG6J7C.js → chunk-GCYTI3DE.js} +40 -31
  55. package/dist/{chunk-GNSFLJAA.js → chunk-GJFAMOGK.js} +3 -3
  56. package/dist/{chunk-VNSXLA6G.js → chunk-H7KENAZO.js} +16 -12
  57. package/dist/{chunk-KFNWFNAA.js → chunk-HBPDFCQY.js} +3 -3
  58. package/dist/{chunk-467TVMQL.js → chunk-HHKO6SKY.js} +2 -2
  59. package/dist/{chunk-6K2M4VSR.js → chunk-HQQNCY7W.js} +21 -8
  60. package/dist/{chunk-ZJ3LS7DW.js → chunk-HWX6ZHF3.js} +2 -2
  61. package/dist/{chunk-Q62FEYK3.js → chunk-ICPJPQ5C.js} +2 -2
  62. package/dist/{chunk-MVN25IF6.js → chunk-IM6PDDCE.js} +4 -4
  63. package/dist/{chunk-65WJYYKJ.js → chunk-INE5YJBZ.js} +11 -6
  64. package/dist/{chunk-EDA6C7MV.js → chunk-J6QROYDA.js} +13 -9
  65. package/dist/{chunk-3ODS2VGL.js → chunk-J7KJR3R6.js} +116 -96
  66. package/dist/{chunk-JEUJOX5X.js → chunk-J7TLCB2Q.js} +2 -2
  67. package/dist/{chunk-GD6L76WD.js → chunk-JRCOYRRH.js} +19 -7
  68. package/dist/{chunk-G3PF3S7P.js → chunk-K2I2XOZD.js} +9 -9
  69. package/dist/{chunk-5PDTIBLV.js → chunk-K4EOKJA6.js} +17 -7
  70. package/dist/{chunk-5SVOCD5W.js → chunk-KGVZ5VGH.js} +10 -7
  71. package/dist/{chunk-QHI5XVUJ.js → chunk-LBMS4AW6.js} +20 -19
  72. package/dist/{chunk-FTBZV6NE.js → chunk-LGT3PZCJ.js} +22 -14
  73. package/dist/{chunk-E7Y3SYKW.js → chunk-LTXOLDUZ.js} +9 -6
  74. package/dist/{chunk-GTWKD3QT.js → chunk-MUE65OTD.js} +5 -4
  75. package/dist/{chunk-TRM2J7ZN.js → chunk-MUVJ57EP.js} +10 -14
  76. package/dist/{chunk-RBHWPDBB.js → chunk-NNS4E7CW.js} +6 -4
  77. package/dist/{chunk-NNAAJVBU.js → chunk-NR5HCAUD.js} +1 -1
  78. package/dist/{chunk-NEQ6GJXB.js → chunk-ONU3U4GL.js} +2 -2
  79. package/dist/{chunk-XEQXCIBC.js → chunk-PRI2OD4E.js} +10 -3
  80. package/dist/{chunk-U6EQI3U6.js → chunk-QBZYACOG.js} +3 -3
  81. package/dist/{chunk-5PZT4DQG.js → chunk-QGATPIPX.js} +15 -9
  82. package/dist/{chunk-YGJZWZTY.js → chunk-QHXCAEMX.js} +7 -4
  83. package/dist/{chunk-RLFVAKEO.js → chunk-QJMKPUYK.js} +15 -5
  84. package/dist/{chunk-Z6XJQ6KO.js → chunk-QVENJMNX.js} +2 -2
  85. package/dist/{chunk-GROLTAWZ.js → chunk-QZX5S6R3.js} +2 -2
  86. package/dist/{chunk-TMACGPW5.js → chunk-R3YSD62R.js} +3 -3
  87. package/dist/{chunk-332ZR4QU.js → chunk-REJAIQ5S.js} +4 -4
  88. package/dist/{chunk-5F5ELR3V.js → chunk-ROOE4R4Y.js} +8 -5
  89. package/dist/{chunk-XHVV4NVW.js → chunk-RT7ACF77.js} +12 -2
  90. package/dist/{chunk-GGHRAITI.js → chunk-SMRFPVLQ.js} +3 -3
  91. package/dist/{chunk-JSSX2SX4.js → chunk-SWSIKFEB.js} +2 -2
  92. package/dist/{chunk-DY7XLRHK.js → chunk-T4A4TSTJ.js} +14 -15
  93. package/dist/{chunk-VB4UJ3H2.js → chunk-TJVLKNGR.js} +20 -10
  94. package/dist/{chunk-FC5I2KXV.js → chunk-TPFKKXCB.js} +3 -3
  95. package/dist/{chunk-AXW3M6OQ.js → chunk-TTIM6YTT.js} +28 -18
  96. package/dist/{chunk-WJ7RW65H.js → chunk-UBLHQTLV.js} +13 -12
  97. package/dist/{chunk-AE7II3E3.js → chunk-UNURMIQO.js} +2 -2
  98. package/dist/{chunk-PZDBOK2Q.js → chunk-VILVLS7P.js} +5 -3
  99. package/dist/{chunk-3YSQZ75W.js → chunk-VQOCMUWI.js} +37 -26
  100. package/dist/{chunk-P6T66CCZ.js → chunk-WBM7ZNDI.js} +3 -2
  101. package/dist/{chunk-4QZ43D7I.js → chunk-XD6ZYURY.js} +9 -4
  102. package/dist/{chunk-3JLKYGBQ.js → chunk-YIBAWQGJ.js} +6 -3
  103. package/dist/{chunk-ZO27FGJS.js → chunk-YTMTPUH4.js} +7 -4
  104. package/dist/{chunk-6BQFET7X.js → chunk-Z5QVYKR7.js} +11 -3
  105. package/dist/{chunk-KJGG2JKQ.js → chunk-ZEF5M5MB.js} +52 -45
  106. package/dist/{chunk-32XPAAET.js → chunk-ZJV7GYR4.js} +3 -3
  107. package/dist/{chunk-2ILHQOL3.js → chunk-ZNWAYU6N.js} +11 -7
  108. package/dist/cli.cjs +146 -145
  109. package/dist/clock.js +16 -22
  110. package/dist/dgmo-router-X7ZGAPIE.js +86 -0
  111. package/dist/{dimensions-F7B5C4BJ.js → dimensions-45H6JQEY.js} +6 -6
  112. package/dist/editor.js +4 -2
  113. package/dist/element.js +126 -124
  114. package/dist/element.mjs +952 -492
  115. package/dist/{flowchart-parser-MY53QWTZ.js → flowchart-parser-UKELHBSB.js} +4 -4
  116. package/dist/{flowchart-renderer-AQSMEMYF.js → flowchart-renderer-MNCDS7MV.js} +7 -7
  117. package/dist/highlight.d.ts +21 -1
  118. package/dist/highlight.js +93 -3
  119. package/dist/index.js +51 -51
  120. package/dist/{layout-JDJAEQ3P.js → layout-2L3WMRYU.js} +4 -4
  121. package/dist/{layout-MUPRALE5.js → layout-A4XWNVID.js} +4 -4
  122. package/dist/{layout-46366KBT.js → layout-A5UHRWVH.js} +3 -3
  123. package/dist/{layout-HYZPWAK5.js → layout-GM4UGR7B.js} +4 -3
  124. package/dist/{layout-CBCLPMSG.js → layout-GQQJXNYH.js} +4 -4
  125. package/dist/{layout-YVTNOTN4.js → layout-IIE2S5FK.js} +3 -3
  126. package/dist/{layout-4DIUOX2T.js → layout-VMCRX66I.js} +4 -4
  127. package/dist/{palettes-PRJ2RI6D.js → palettes-UDLZ2SA4.js} +2 -2
  128. package/dist/{parser-BKI42XBQ.js → parser-2ECN6JA2.js} +4 -4
  129. package/dist/{parser-C3D7MVXY.js → parser-4WTIHM5J.js} +3 -3
  130. package/dist/{parser-5A2UWU6B.js → parser-5H2BTSJQ.js} +3 -3
  131. package/dist/{parser-OK2ILHRT.js → parser-75KVXUNS.js} +4 -4
  132. package/dist/{parser-SRVFR7PM.js → parser-774AC53T.js} +4 -4
  133. package/dist/{parser-BEPSWJAD.js → parser-BE4YCSRU.js} +3 -3
  134. package/dist/{parser-B77S5SZM.js → parser-CNGUQUQI.js} +3 -3
  135. package/dist/{parser-2Q2T4C3B.js → parser-DEUUSQIN.js} +7 -7
  136. package/dist/{parser-5PDYJGWA.js → parser-DQAFLUJB.js} +4 -4
  137. package/dist/{parser-KKTJ6M3Y.js → parser-EYCKNKQA.js} +5 -5
  138. package/dist/{parser-UKFFZCFJ.js → parser-FXISIU6A.js} +4 -4
  139. package/dist/{parser-UMWPLORP.js → parser-GTB4XC7P.js} +5 -5
  140. package/dist/{parser-Z4TZV2CB.js → parser-GVEPAUSD.js} +4 -4
  141. package/dist/{parser-AIMHGJRR.js → parser-HSQGTY4G.js} +4 -4
  142. package/dist/{parser-OUTPNJWC.js → parser-HVKRINUS.js} +3 -3
  143. package/dist/{parser-JA7JQ7NF.js → parser-J5MIEYO4.js} +5 -5
  144. package/dist/parser-KMZIXLDZ.js +13 -0
  145. package/dist/{parser-CDG7CHV5.js → parser-LJHXWSXU.js} +3 -3
  146. package/dist/{parser-PORDUX5E.js → parser-PT3W72G5.js} +4 -4
  147. package/dist/{parser-CZOJ7XQ6.js → parser-SBJQDPHL.js} +4 -4
  148. package/dist/{parser-I6GGFKOQ.js → parser-SUWWWCMX.js} +3 -3
  149. package/dist/{parser-AZJ25OKK.js → parser-SXDRNZOA.js} +4 -4
  150. package/dist/parser-UMILOW3M.js +14 -0
  151. package/dist/{parser-GKLZKEIK.js → parser-UP3AZ367.js} +4 -4
  152. package/dist/{parser-57ILIFZ2.js → parser-WHPRV3X5.js} +5 -5
  153. package/dist/{parser-H6ABKHZZ.js → parser-WX3UODSJ.js} +4 -4
  154. package/dist/{parser-FQ6GZFMR.js → parser-XCIEN3KN.js} +4 -4
  155. package/dist/{parser-E2RL6JYF.js → parser-XIRTUMVN.js} +5 -5
  156. package/dist/{parser-3A42DZ72.js → parser-YKCGIG45.js} +3 -3
  157. package/dist/{parser-EH5VE7ZN.js → parser-YKYMQG3B.js} +4 -4
  158. package/dist/{parser-6ZKABF5S.js → parser-ZGM2OJ6Y.js} +5 -5
  159. package/dist/{parser-4RFTKAQX.js → parser-ZL5QUFVH.js} +4 -4
  160. package/dist/pert.d.ts +2 -2
  161. package/dist/{renderer-RYR3TJ46.js → renderer-3F7OS2AX.js} +10 -10
  162. package/dist/{renderer-TGTUABCI.js → renderer-4QB4K7Q3.js} +6 -6
  163. package/dist/{renderer-GHPZMFU2.js → renderer-5DAKMIU2.js} +3 -3
  164. package/dist/{renderer-3K3IB7D5.js → renderer-5H4SY7YY.js} +6 -6
  165. package/dist/{renderer-QIWVHWZO.js → renderer-5PIQPFOX.js} +4 -3
  166. package/dist/{renderer-NKJ24TEA.js → renderer-6MU37QF5.js} +6 -6
  167. package/dist/{renderer-QXPP4TA2.js → renderer-AQVMWJ4M.js} +9 -9
  168. package/dist/{renderer-2AUFT3E2.js → renderer-BDDW6K7N.js} +6 -6
  169. package/dist/{renderer-OYO67VZK.js → renderer-BNB3VIDY.js} +7 -7
  170. package/dist/{renderer-QXGN5H3A.js → renderer-CQY6ATOS.js} +5 -5
  171. package/dist/{renderer-CO2DW7S7.js → renderer-CVW75CXL.js} +9 -9
  172. package/dist/{renderer-KQB7UGDS.js → renderer-DT4XRFEP.js} +4 -3
  173. package/dist/{renderer-GQIESYEM.js → renderer-ERHBSTQT.js} +6 -6
  174. package/dist/{renderer-UV6MI64M.js → renderer-HSHHVYWF.js} +4 -3
  175. package/dist/{renderer-ARMJBP6C.js → renderer-IDPVUFNB.js} +8 -8
  176. package/dist/{renderer-QRWACQRI.js → renderer-ILX6BGKR.js} +6 -6
  177. package/dist/{renderer-F7U3MFCV.js → renderer-JP663HKG.js} +7 -7
  178. package/dist/{renderer-RGIYOTKJ.js → renderer-KNFTTOBL.js} +8 -8
  179. package/dist/{renderer-3YNIWF5I.js → renderer-MVUZBESR.js} +5 -5
  180. package/dist/{renderer-HYGHO4SJ.js → renderer-N4EBR2FV.js} +8 -8
  181. package/dist/{renderer-3YPZHMOU.js → renderer-NHO46CT2.js} +3 -3
  182. package/dist/{renderer-SRKDNDFB.js → renderer-NO2QJ5LZ.js} +7 -7
  183. package/dist/{renderer-2HTNBIF2.js → renderer-OGFV5RXX.js} +8 -8
  184. package/dist/{renderer-HCKJDFXD.js → renderer-PDLESJMS.js} +9 -9
  185. package/dist/{renderer-66MERVQ2.js → renderer-T4MTNINC.js} +6 -6
  186. package/dist/{renderer-RHT4MHFU.js → renderer-TOUGFGTM.js} +7 -7
  187. package/dist/{renderer-EDJ2O4S5.js → renderer-U3KPD43Y.js} +8 -8
  188. package/dist/{renderer-4WR6WMVF.js → renderer-X334IJU2.js} +6 -6
  189. package/dist/{renderer-JC3RDUT7.js → renderer-Y5OAMOCR.js} +6 -6
  190. package/dist/{renderer-GD2COXVL.js → renderer-YONAKAJU.js} +4 -4
  191. package/dist/{renderer-TXJFKPOG.js → renderer-YWMI6Y2U.js} +8 -8
  192. package/dist/{renderer-6RKQPNJI.js → renderer-ZWIH4WDW.js} +7 -7
  193. package/dist/{renderer-radial-FWABAZHB.js → renderer-radial-7CGZMVMS.js} +7 -7
  194. package/dist/{state-parser-6T6CNMPX.js → state-parser-BATWAID2.js} +4 -4
  195. package/dist/{state-renderer-AWZ3ECAX.js → state-renderer-3FKZJ3LP.js} +7 -7
  196. package/docs/ai-integration.md +15 -19
  197. package/docs/language-reference.md +13 -11
  198. package/package.json +1 -1
  199. package/dist/dgmo-router-Y2VEX46B.js +0 -86
  200. package/dist/parser-6BJEXUFX.js +0 -13
  201. package/dist/parser-OK22AC6Y.js +0 -14
package/dist/element.mjs CHANGED
@@ -623,6 +623,23 @@ function extractColor(label, palette, diagnostics, line11) {
623
623
  ...color !== void 0 && { color }
624
624
  };
625
625
  }
626
+ function fillModeFromToken(token) {
627
+ switch (token.trim().toLowerCase()) {
628
+ case "fill-solid":
629
+ return "solid";
630
+ case "fill-outline":
631
+ return "outline";
632
+ case "fill-tint":
633
+ return "tint";
634
+ default:
635
+ return null;
636
+ }
637
+ }
638
+ function fillModeFromOptions(options) {
639
+ if (options["fill-solid"] === "on") return "solid";
640
+ if (options["fill-outline"] === "on") return "outline";
641
+ return void 0;
642
+ }
626
643
  function recognizeGlobalBoolean(token) {
627
644
  const t = token.trim().toLowerCase();
628
645
  return GLOBAL_BOOLEANS.has(t) ? t : null;
@@ -630,6 +647,9 @@ function recognizeGlobalBoolean(token) {
630
647
  function tryParseSharedOption(line11, options) {
631
648
  const key = recognizeGlobalBoolean(line11);
632
649
  if (key) {
650
+ if (FILL_FAMILY_TOKENS.has(key)) {
651
+ for (const t of FILL_FAMILY_TOKENS) delete options[t];
652
+ }
633
653
  options[key] = "on";
634
654
  return true;
635
655
  }
@@ -984,7 +1004,7 @@ function warnUnknownMetaKeys(meta, registry, warn, nameToScan) {
984
1004
  }
985
1005
  }
986
1006
  }
987
- var RECOGNIZED_COLOR_SET, ALL_CHART_TYPES, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, RESERVED_KEY_RE, AS_ALIAS_RE, POTENTIAL_META_RE;
1007
+ var RECOGNIZED_COLOR_SET, ALL_CHART_TYPES, OPTION_NOCOLON_RE, GLOBAL_BOOLEANS, FILL_FAMILY_TOKENS, RESERVED_KEY_RE, AS_ALIAS_RE, POTENTIAL_META_RE;
988
1008
  var init_parsing = __esm({
989
1009
  "src/utils/parsing.ts"() {
990
1010
  "use strict";
@@ -1051,10 +1071,17 @@ var init_parsing = __esm({
1051
1071
  ]);
1052
1072
  OPTION_NOCOLON_RE = /^([a-z][a-z0-9-]*)\s+(.+)$/i;
1053
1073
  GLOBAL_BOOLEANS = /* @__PURE__ */ new Set([
1054
- "solid-fill",
1074
+ "fill-tint",
1075
+ "fill-solid",
1076
+ "fill-outline",
1055
1077
  "no-title",
1056
1078
  "no-notes"
1057
1079
  ]);
1080
+ FILL_FAMILY_TOKENS = /* @__PURE__ */ new Set([
1081
+ "fill-tint",
1082
+ "fill-solid",
1083
+ "fill-outline"
1084
+ ]);
1058
1085
  RESERVED_KEY_RE = /^[A-Za-z][A-Za-z0-9_-]*$/;
1059
1086
  AS_ALIAS_RE = /\s+as\s+([A-Za-z][A-Za-z0-9_]{0,11})$/;
1060
1087
  POTENTIAL_META_RE = /\b([\w-]+)\s*:/;
@@ -1304,6 +1331,20 @@ function monthNameToNum(raw) {
1304
1331
  i = MONTHS_ABBR.indexOf(t.slice(0, 3));
1305
1332
  return i >= 0 ? i + 1 : 0;
1306
1333
  }
1334
+ function scanMonthNameDates(line11) {
1335
+ const spans = [];
1336
+ const re = new RegExp(MONTH_NAME_SCAN_RE.source, "g");
1337
+ let m;
1338
+ while ((m = re.exec(line11)) !== null) {
1339
+ const month = m[2] ?? m[3] ?? "";
1340
+ if (monthNameToNum(month) <= 0) {
1341
+ re.lastIndex = m.index + 1;
1342
+ continue;
1343
+ }
1344
+ spans.push({ start: m.index, end: m.index + m[0].length });
1345
+ }
1346
+ return spans;
1347
+ }
1307
1348
  function matchTime(rest) {
1308
1349
  const m = rest.match(TIME_RE);
1309
1350
  if (!m) return { hour: 0, minute: 0, second: 0, hasTime: false, consumed: 0 };
@@ -1520,7 +1561,7 @@ function normalizeDate(raw, opts = {}) {
1520
1561
  const year = res.token.year ?? opts.year ?? opts.currentYear ?? (/* @__PURE__ */ new Date()).getFullYear();
1521
1562
  return toInternal(res.token, year);
1522
1563
  }
1523
- var MONTHS_FULL, MONTHS_ABBR, ERA_RE, ISO_RE, MONTH_D_RE, D_MONTH_RE, SLASH_RE, TIME_RE;
1564
+ var MONTHS_FULL, MONTHS_ABBR, MONTH_NAME_SCAN_RE, ERA_RE, ISO_RE, MONTH_D_RE, D_MONTH_RE, SLASH_RE, TIME_RE;
1524
1565
  var init_date = __esm({
1525
1566
  "src/utils/date.ts"() {
1526
1567
  "use strict";
@@ -1552,6 +1593,7 @@ var init_date = __esm({
1552
1593
  "nov",
1553
1594
  "dec"
1554
1595
  ];
1596
+ MONTH_NAME_SCAN_RE = /\b(\d{1,2})\s+([A-Za-z]{3,9})\.?(?:\s+\d{4})?|\b([A-Za-z]{3,9})\.?\s+(\d{1,2})(?:,?\s+\d{4})?/g;
1555
1597
  ERA_RE = /^(\d{1,4})(?:-(\d{2})(?:-(\d{2}))?)?\s+(BCE|BC|CE|AD)\b/i;
1556
1598
  ISO_RE = /^(\d{4})(?:-(\d{2})(?:-(\d{2}))?)?/;
1557
1599
  MONTH_D_RE = /^([A-Za-z]{3,9})\.?\s+(\d{1,2})(?:,?\s+(\d{4}))?/;
@@ -2392,7 +2434,7 @@ function parseVisualizationFull(content, palette) {
2392
2434
  }
2393
2435
  continue;
2394
2436
  }
2395
- if (!/^(era|marker|tag|sort|active-tag|swimlanes|no-scale|lane-by)\b/i.test(
2437
+ if (!/^(era|marker|tag|sort|active-tag|swimlanes|no-scale|lane-by|fill-tint|fill-solid|fill-outline)\b/i.test(
2396
2438
  line11
2397
2439
  ) && !line11.startsWith("[")) {
2398
2440
  warn(lineNumber, `Expected a date at the start \u2014 e.g., '1718 ${line11}'`);
@@ -2400,7 +2442,9 @@ function parseVisualizationFull(content, palette) {
2400
2442
  }
2401
2443
  }
2402
2444
  if (result.type === "venn") {
2403
- if (/^(solid-fill|no-name|no-value|no-percent|no-title)$/i.test(line11)) {
2445
+ if (/^(fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|no-title)$/i.test(
2446
+ line11
2447
+ )) {
2404
2448
  } else if (/\+/.test(line11)) {
2405
2449
  const knownSetRefs = /* @__PURE__ */ new Set();
2406
2450
  for (const s of result.vennSets) {
@@ -2434,7 +2478,9 @@ function parseVisualizationFull(content, palette) {
2434
2478
  continue;
2435
2479
  }
2436
2480
  }
2437
- if (!/^(solid-fill|no-name|no-value|no-percent|no-title)$/i.test(line11)) {
2481
+ if (!/^(fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|no-title)$/i.test(
2482
+ line11
2483
+ )) {
2438
2484
  const { label: lineWithoutColor, colorName } = peelTrailingColorName(line11);
2439
2485
  let color = null;
2440
2486
  if (colorName) {
@@ -2601,8 +2647,10 @@ function parseVisualizationFull(content, palette) {
2601
2647
  result.noPercent = true;
2602
2648
  continue;
2603
2649
  }
2604
- if (bareToken === "solid-fill") {
2605
- result.solidFill = true;
2650
+ const fillFamily = fillModeFromToken(bareToken);
2651
+ if (fillFamily !== null) {
2652
+ if (fillFamily === "tint") delete result.fillMode;
2653
+ else result.fillMode = fillFamily;
2606
2654
  continue;
2607
2655
  }
2608
2656
  if (bareToken === "no-title") {
@@ -3367,7 +3415,8 @@ function themeBaseBg(palette, isDark) {
3367
3415
  return isDark ? palette.surface : palette.bg;
3368
3416
  }
3369
3417
  function shapeFill(palette, intent, isDark, opts) {
3370
- if (opts?.solid) return intent;
3418
+ if (opts?.mode === "solid") return intent;
3419
+ if (opts?.mode === "outline") return themeBaseBg(palette, isDark);
3371
3420
  return mix(intent, themeBaseBg(palette, isDark), 25);
3372
3421
  }
3373
3422
  function getSeriesColors(palette) {
@@ -5667,7 +5716,7 @@ function getEraColors(palette) {
5667
5716
  palette.colors.purple
5668
5717
  ];
5669
5718
  }
5670
- function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter, onLeave, hasScale = false, _tooltip = null, palette, reservedLabelY) {
5719
+ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter, onLeave, hasScale = false, _tooltip = null, palette, reservedLabelY, fillMode, outlineBg) {
5671
5720
  const eraColors = palette ? getEraColors(palette) : ["#3b6ea5", "#5b9357", "#c9a227", "#cc7a33", "#7d5ba6"];
5672
5721
  eras.forEach((era, i) => {
5673
5722
  const startVal = parseTimelineDate(era.startDate);
@@ -5681,10 +5730,20 @@ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter
5681
5730
  let labelEl;
5682
5731
  let displayLabel = era.label;
5683
5732
  let truncated = false;
5733
+ const outlineEra = fillMode === "outline" && outlineBg !== void 0;
5734
+ const applyEraFill = (rect2) => {
5735
+ if (outlineEra) {
5736
+ rect2.attr("fill", outlineBg).attr("stroke", color).attr("stroke-width", 1);
5737
+ } else {
5738
+ rect2.attr("fill", color).attr("opacity", 0.08);
5739
+ }
5740
+ };
5684
5741
  if (isVertical) {
5685
5742
  const y = Math.min(start, end);
5686
5743
  const h = Math.abs(end - start);
5687
- eraG.append("rect").attr("x", 0).attr("y", y).attr("width", innerWidth).attr("height", h).attr("fill", color).attr("opacity", 0.08);
5744
+ applyEraFill(
5745
+ eraG.append("rect").attr("x", 0).attr("y", y).attr("width", innerWidth).attr("height", h)
5746
+ );
5688
5747
  labelEl = eraG.append("text").attr("x", 6).attr("y", y + 18).attr("text-anchor", "start").attr("fill", color).attr("font-size", "13px").attr("font-weight", "600").attr("opacity", 0.8).text(displayLabel);
5689
5748
  } else {
5690
5749
  const x = Math.min(start, end);
@@ -5692,7 +5751,9 @@ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter
5692
5751
  const useReservedRow = reservedLabelY != null;
5693
5752
  const rectTop = useReservedRow ? 0 : hasScale ? -48 : 0;
5694
5753
  const labelY = useReservedRow ? reservedLabelY : hasScale ? -32 : 18;
5695
- eraG.append("rect").attr("x", x).attr("y", rectTop).attr("width", w).attr("height", innerHeight - rectTop).attr("fill", color).attr("opacity", 0.08);
5754
+ applyEraFill(
5755
+ eraG.append("rect").attr("x", x).attr("y", rectTop).attr("width", w).attr("height", innerHeight - rectTop)
5756
+ );
5696
5757
  if (useReservedRow) {
5697
5758
  const maxW = Math.max(0, w - 8);
5698
5759
  displayLabel = truncateLegendText(era.label, 13, maxW);
@@ -5709,7 +5770,7 @@ function renderEras(g, eras, scale, isVertical, innerWidth, innerHeight, onEnter
5709
5770
  });
5710
5771
  });
5711
5772
  }
5712
- function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, onEnter, onLeave, _hasScale = false, _tooltip = null, palette, reservedLabelY) {
5773
+ function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, onEnter, onLeave, _hasScale = false, _tooltip = null, palette, reservedLabelY, fillMode, outlineBg) {
5713
5774
  const defaultColor = palette?.accent || "#3a9188";
5714
5775
  const positions = markers.map((m) => {
5715
5776
  const v = parseTimelineDate(m.date);
@@ -5724,14 +5785,24 @@ function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, o
5724
5785
  const color = marker.color || defaultColor;
5725
5786
  const lineOpacity = 0.5;
5726
5787
  const diamondSize = 5;
5788
+ const outlineDiamond = fillMode === "outline" && outlineBg !== void 0;
5789
+ const applyDiamondFill = (path) => {
5790
+ if (outlineDiamond) {
5791
+ path.attr("fill", outlineBg).attr("stroke", color).attr("stroke-width", 1.25).attr("opacity", 0.9);
5792
+ } else {
5793
+ path.attr("fill", color).attr("opacity", 0.9);
5794
+ }
5795
+ };
5727
5796
  const markerG = g.append("g").attr("class", "tl-marker").attr("data-marker-date", String(dateVal)).attr("data-line-number", String(marker.lineNumber)).style("cursor", "pointer");
5728
5797
  if (isVertical) {
5729
5798
  markerG.append("line").attr("x1", 0).attr("y1", pos).attr("x2", innerWidth).attr("y2", pos).attr("stroke", color).attr("stroke-width", 1.5).attr("stroke-dasharray", "6 4").attr("opacity", lineOpacity);
5730
5799
  markerG.append("text").attr("x", -diamondSize - 8).attr("y", pos - diamondSize - 4).attr("text-anchor", "middle").attr("fill", color).attr("font-size", "11px").attr("font-weight", "600").text(marker.label);
5731
- markerG.append("path").attr(
5732
- "d",
5733
- `M${-diamondSize - 8},${pos} l${diamondSize},-${diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} Z`
5734
- ).attr("fill", color).attr("opacity", 0.9);
5800
+ applyDiamondFill(
5801
+ markerG.append("path").attr(
5802
+ "d",
5803
+ `M${-diamondSize - 8},${pos} l${diamondSize},-${diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} Z`
5804
+ )
5805
+ );
5735
5806
  markerG.on("mouseenter", function() {
5736
5807
  onEnter(dateVal);
5737
5808
  }).on("mouseleave", function() {
@@ -5757,10 +5828,12 @@ function renderMarkers(g, markers, scale, isVertical, innerWidth, innerHeight, o
5757
5828
  truncated = displayLabel !== marker.label;
5758
5829
  }
5759
5830
  const labelEl = markerG.append("text").attr("x", pos).attr("y", labelY).attr("text-anchor", "middle").attr("fill", color).attr("font-size", "11px").attr("font-weight", "600").text(displayLabel);
5760
- markerG.append("path").attr(
5761
- "d",
5762
- `M${pos},${diamondY - diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} l-${diamondSize},-${diamondSize} Z`
5763
- ).attr("fill", color).attr("opacity", 0.9);
5831
+ applyDiamondFill(
5832
+ markerG.append("path").attr(
5833
+ "d",
5834
+ `M${pos},${diamondY - diamondSize} l${diamondSize},${diamondSize} l-${diamondSize},${diamondSize} l-${diamondSize},-${diamondSize} Z`
5835
+ )
5836
+ );
5764
5837
  markerG.append("line").attr("x1", pos).attr("y1", lineTop).attr("x2", pos).attr("y2", innerHeight).attr("stroke", color).attr("stroke-width", 1.5).attr("stroke-dasharray", "6 4").attr("opacity", lineOpacity);
5765
5838
  markerG.on("mouseenter", function() {
5766
5839
  onEnter(dateVal);
@@ -5887,7 +5960,7 @@ function renderTimelineGroupLegend(g, groups, groupColorMap, textColor, palette,
5887
5960
  }
5888
5961
  function setupTimeline(container, parsed, palette, isDark, exportDims, activeTagGroup, swimlaneTagGroup) {
5889
5962
  d3Selection3.select(container).selectAll(":not([data-d3-tooltip])").remove();
5890
- const solid = parsed.solidFill === true;
5963
+ const fillMode = parsed.fillMode;
5891
5964
  const {
5892
5965
  timelineEvents,
5893
5966
  timelineGroups,
@@ -6012,7 +6085,7 @@ function setupTimeline(container, parsed, palette, isDark, exportDims, activeTag
6012
6085
  height,
6013
6086
  isVertical,
6014
6087
  tooltip,
6015
- solid,
6088
+ fillMode,
6016
6089
  textColor,
6017
6090
  mutedColor,
6018
6091
  bgColor,
@@ -6142,7 +6215,7 @@ function makeTimelineHoverHelpers() {
6142
6215
  }
6143
6216
  function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setup, hovers, onClickItem, exportDims, swimlaneTagGroup, activeTagGroup, onTagStateChange, viewMode, exportMode) {
6144
6217
  if (parsed.timelineTagGroups.length === 0) return;
6145
- const { width, textColor, groupColorMap, solid } = setup;
6218
+ const { width, textColor, groupColorMap, fillMode } = setup;
6146
6219
  const { FADE_OPACITY: FADE_OPACITY2, fadeReset, fadeToTagValue } = hovers;
6147
6220
  const title = parsed.noTitle ? null : parsed.title;
6148
6221
  const { timelineEvents } = parsed;
@@ -6295,8 +6368,8 @@ function renderTimelineTagLegendOverlay(container, parsed, palette, isDark, setu
6295
6368
  } else {
6296
6369
  color = ev.group && groupColorMap.has(ev.group) ? groupColorMap.get(ev.group) : textColor;
6297
6370
  }
6298
- el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
6299
- el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color);
6371
+ el.selectAll("rect").attr("fill", shapeFill(palette, color, isDark, { mode: fillMode })).attr("stroke", color);
6372
+ el.selectAll("circle:not(.tl-event-point-outline)").attr("fill", shapeFill(palette, color, isDark, { mode: fillMode })).attr("stroke", color);
6300
6373
  });
6301
6374
  };
6302
6375
  var drawSwimlaneIcon3 = drawSwimlaneIcon4, relayout = relayout2, drawLegend = drawLegend2, recolorEvents = recolorEvents2;
@@ -6329,7 +6402,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6329
6402
  width,
6330
6403
  height,
6331
6404
  tooltip,
6332
- solid,
6405
+ fillMode,
6333
6406
  textColor,
6334
6407
  bgColor,
6335
6408
  bg,
@@ -6407,7 +6480,9 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6407
6480
  timelineScale,
6408
6481
  tooltip,
6409
6482
  palette,
6410
- eraReserve ? eraLabelY : void 0
6483
+ eraReserve ? eraLabelY : void 0,
6484
+ fillMode,
6485
+ bg
6411
6486
  );
6412
6487
  renderMarkers(
6413
6488
  g,
@@ -6421,7 +6496,9 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6421
6496
  timelineScale,
6422
6497
  tooltip,
6423
6498
  palette,
6424
- markerReserve ? markerLabelY : void 0
6499
+ markerReserve ? markerLabelY : void 0,
6500
+ fillMode,
6501
+ bg
6425
6502
  );
6426
6503
  if (timelineScale) {
6427
6504
  renderTimeScale(
@@ -6492,7 +6569,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6492
6569
  const rectW = Math.max(x2 - x, 4);
6493
6570
  const estLabelWidth = ev.label.length * sCharW + ctx.aesthetic(16);
6494
6571
  const labelFitsInside = rectW >= estLabelWidth;
6495
- let fill2 = shapeFill(palette, color, isDark, { solid });
6572
+ let fill2 = shapeFill(palette, color, isDark, { mode: fillMode });
6496
6573
  let stroke2 = color;
6497
6574
  if (ev.uncertain) {
6498
6575
  const gradientId = `uncertain-ts-${ev.lineNumber}`;
@@ -6503,7 +6580,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6503
6580
  { offset: "0%", opacity: 1 },
6504
6581
  { offset: "80%", opacity: 1 },
6505
6582
  { offset: "100%", opacity: 0 }
6506
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
6583
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", fillMode === "outline" ? bg : mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
6507
6584
  defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
6508
6585
  { offset: "0%", opacity: 1 },
6509
6586
  { offset: "80%", opacity: 1 },
@@ -6528,7 +6605,7 @@ function renderTimelineHorizontalTimeSort(container, parsed, palette, isDark, se
6528
6605
  const wouldFlipLeft = x > innerWidth * 0.6;
6529
6606
  const labelFitsLeft = x - sPointGap - estLabelWidth > 0;
6530
6607
  const flipLeft = wouldFlipLeft && labelFitsLeft;
6531
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", sPointStroke);
6608
+ evG.append("circle").attr("cx", x).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, color, isDark, { mode: fillMode })).attr("stroke", color).attr("stroke-width", sPointStroke);
6532
6609
  evG.append("text").attr("x", flipLeft ? x - sPointGap : x + sPointGap).attr("y", y).attr("dy", "0.35em").attr("text-anchor", flipLeft ? "end" : "start").attr("fill", textColor).attr("font-size", `${sEventFontSm}px`).text(ev.label);
6533
6610
  }
6534
6611
  });
@@ -6538,7 +6615,7 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6538
6615
  width,
6539
6616
  height,
6540
6617
  tooltip,
6541
- solid,
6618
+ fillMode,
6542
6619
  textColor,
6543
6620
  bgColor,
6544
6621
  bg,
@@ -6649,7 +6726,9 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6649
6726
  timelineScale,
6650
6727
  tooltip,
6651
6728
  palette,
6652
- eraReserve ? eraLabelY : void 0
6729
+ eraReserve ? eraLabelY : void 0,
6730
+ fillMode,
6731
+ bg
6653
6732
  );
6654
6733
  renderMarkers(
6655
6734
  g,
@@ -6663,7 +6742,9 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6663
6742
  timelineScale,
6664
6743
  tooltip,
6665
6744
  palette,
6666
- markerReserve ? markerLabelY : void 0
6745
+ markerReserve ? markerLabelY : void 0,
6746
+ fillMode,
6747
+ bg
6667
6748
  );
6668
6749
  if (timelineScale) {
6669
6750
  renderTimeScale(
@@ -6692,7 +6773,7 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6692
6773
  const sBandAccentW = ctx.structural(4);
6693
6774
  const clipId = `tl-band-clip-${tlBandClipCounter++}`;
6694
6775
  g.append("clipPath").attr("id", clipId).append("rect").attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", bandH).attr("rx", sBandRx);
6695
- g.append("rect").attr("class", "tl-group-header-bg").attr("data-group", lane.name).attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", bandH).attr("rx", sBandRx).attr("fill", shapeFill(palette, laneColor, isDark, { solid })).style("pointer-events", "none");
6776
+ g.append("rect").attr("class", "tl-group-header-bg").attr("data-group", lane.name).attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", bandH).attr("rx", sBandRx).attr("fill", shapeFill(palette, laneColor, isDark, { mode: fillMode })).style("pointer-events", "none");
6696
6777
  g.append("rect").attr("class", "tl-group-header-accent").attr("data-group", lane.name).attr("x", bandX).attr("y", bandY).attr("width", sBandAccentW).attr("height", bandH).attr("fill", laneColor).attr("clip-path", `url(#${clipId})`).style("pointer-events", "none");
6697
6778
  const headerG = g.append("g").attr("class", "tl-group-header").attr("data-group", lane.name).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, lane.name)).on("mouseleave", () => fadeReset(g)).on("click", () => toggleGroup(lane.name));
6698
6779
  headerG.append("text").attr("x", -margin.left + ctx.aesthetic(10)).attr("y", curY + sBarH / 2).attr("dy", "0.35em").attr("text-anchor", "start").attr("fill", textColor).attr("font-size", `${sLaneHeaderFont}px`).attr("font-weight", "600").text(`${toggleIcon} ${lane.name}`);
@@ -6705,7 +6786,7 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6705
6786
  const sx2 = xScale(laneMaxD);
6706
6787
  const groupBarW = Math.max(sx2 - sx1, ctx.structural(20));
6707
6788
  const groupBarG = g.append("g").attr("class", isCollapsed ? "tl-group-summary" : "tl-group-bar").attr("data-group", lane.name).style("cursor", "pointer").on("mouseenter", () => fadeToGroup(g, lane.name)).on("mouseleave", () => fadeReset(g)).on("click", () => toggleGroup(lane.name));
6708
- groupBarG.append("rect").attr("x", sx1).attr("y", curY).attr("width", groupBarW).attr("height", sBarH).attr("rx", sBarRx).attr("fill", shapeFill(palette, laneColor, isDark, { solid })).attr("stroke", laneColor).attr("stroke-width", sBarStroke);
6789
+ groupBarG.append("rect").attr("x", sx1).attr("y", curY).attr("width", groupBarW).attr("height", sBarH).attr("rx", sBarRx).attr("fill", shapeFill(palette, laneColor, isDark, { mode: fillMode })).attr("stroke", laneColor).attr("stroke-width", sBarStroke);
6709
6790
  }
6710
6791
  if (isCollapsed) {
6711
6792
  curY += rowH + sGroupGap;
@@ -6755,7 +6836,9 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6755
6836
  if (ev.endDate) {
6756
6837
  const x2 = xScale(parseTimelineDate(ev.endDate));
6757
6838
  const rectW = Math.max(x2 - x, 4);
6758
- let fill2 = shapeFill(palette, evColor, isDark, { solid });
6839
+ let fill2 = shapeFill(palette, evColor, isDark, {
6840
+ mode: fillMode
6841
+ });
6759
6842
  let stroke2 = evColor;
6760
6843
  if (ev.uncertain) {
6761
6844
  const gradientId = `uncertain-${ev.lineNumber}`;
@@ -6766,7 +6849,10 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6766
6849
  { offset: "0%", opacity: 1 },
6767
6850
  { offset: "80%", opacity: 1 },
6768
6851
  { offset: "100%", opacity: 0 }
6769
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(evColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
6852
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr(
6853
+ "stop-color",
6854
+ fillMode === "outline" ? bg : mix(evColor, bg, 30)
6855
+ ).attr("stop-opacity", (d) => d.opacity);
6770
6856
  defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "100%").attr("y2", "0%").selectAll("stop").data([
6771
6857
  { offset: "0%", opacity: 1 },
6772
6858
  { offset: "80%", opacity: 1 },
@@ -6777,7 +6863,7 @@ function renderTimelineHorizontalGrouped(container, parsed, palette, isDark, set
6777
6863
  }
6778
6864
  evG.append("rect").attr("x", x).attr("y", y - sBarH / 2).attr("width", rectW).attr("height", sBarH).attr("rx", sBarRx).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sBarStroke);
6779
6865
  } else {
6780
- evG.append("circle").attr("cx", x).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", sPointStroke);
6866
+ evG.append("circle").attr("cx", x).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, evColor, isDark, { mode: fillMode })).attr("stroke", evColor).attr("stroke-width", sPointStroke);
6781
6867
  }
6782
6868
  });
6783
6869
  curY += (lane.events.length + 1) * rowH + sGroupGap;
@@ -6788,7 +6874,7 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6788
6874
  width,
6789
6875
  height,
6790
6876
  tooltip,
6791
- solid,
6877
+ fillMode,
6792
6878
  textColor,
6793
6879
  mutedColor,
6794
6880
  bgColor,
@@ -6881,7 +6967,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6881
6967
  () => fadeReset(g),
6882
6968
  timelineScale,
6883
6969
  tooltip,
6884
- palette
6970
+ palette,
6971
+ void 0,
6972
+ fillMode,
6973
+ bg
6885
6974
  );
6886
6975
  renderMarkers(
6887
6976
  g,
@@ -6894,7 +6983,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6894
6983
  () => fadeReset(g),
6895
6984
  timelineScale,
6896
6985
  tooltip,
6897
- palette
6986
+ palette,
6987
+ void 0,
6988
+ fillMode,
6989
+ bg
6898
6990
  );
6899
6991
  if (timelineScale) {
6900
6992
  renderTimeScale(
@@ -6946,7 +7038,9 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6946
7038
  if (ev.endDate) {
6947
7039
  const y2 = yScale(parseTimelineDate(ev.endDate));
6948
7040
  const rectH = Math.max(y2 - y, 4);
6949
- let fill2 = shapeFill(palette, evColor, isDark, { solid });
7041
+ let fill2 = shapeFill(palette, evColor, isDark, {
7042
+ mode: fillMode
7043
+ });
6950
7044
  let stroke2 = evColor;
6951
7045
  if (ev.uncertain) {
6952
7046
  const gradientId = `uncertain-vg-${ev.lineNumber}`;
@@ -6957,7 +7051,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6957
7051
  { offset: "0%", opacity: 1 },
6958
7052
  { offset: "80%", opacity: 1 },
6959
7053
  { offset: "100%", opacity: 0 }
6960
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(laneColor, bg, 30)).attr("stop-opacity", (d) => d.opacity);
7054
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr(
7055
+ "stop-color",
7056
+ fillMode === "outline" ? bg : mix(laneColor, bg, 30)
7057
+ ).attr("stop-opacity", (d) => d.opacity);
6961
7058
  defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
6962
7059
  { offset: "0%", opacity: 1 },
6963
7060
  { offset: "80%", opacity: 1 },
@@ -6969,7 +7066,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
6969
7066
  evG.append("rect").attr("x", laneCenter - sBarW / 2).attr("y", y).attr("width", sBarW).attr("height", rectH).attr("rx", sBarRx).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sBarStroke);
6970
7067
  evG.append("text").attr("x", laneCenter + sBarW + ctx.aesthetic(2)).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", `${sEventFont}px`).text(ev.label);
6971
7068
  } else {
6972
- evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, evColor, isDark, { solid })).attr("stroke", evColor).attr("stroke-width", sPointStroke);
7069
+ evG.append("circle").attr("cx", laneCenter).attr("cy", y).attr("r", sPointR).attr(
7070
+ "fill",
7071
+ shapeFill(palette, evColor, isDark, { mode: fillMode })
7072
+ ).attr("stroke", evColor).attr("stroke-width", sPointStroke);
6973
7073
  evG.append("text").attr("x", laneCenter + ctx.aesthetic(10)).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", `${sEventFont}px`).text(ev.label);
6974
7074
  }
6975
7075
  }
@@ -7009,7 +7109,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
7009
7109
  () => fadeReset(g),
7010
7110
  timelineScale,
7011
7111
  tooltip,
7012
- palette
7112
+ palette,
7113
+ void 0,
7114
+ fillMode,
7115
+ bg
7013
7116
  );
7014
7117
  renderMarkers(
7015
7118
  g,
@@ -7022,7 +7125,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
7022
7125
  () => fadeReset(g),
7023
7126
  timelineScale,
7024
7127
  tooltip,
7025
- palette
7128
+ palette,
7129
+ void 0,
7130
+ fillMode,
7131
+ bg
7026
7132
  );
7027
7133
  if (timelineScale) {
7028
7134
  renderTimeScale(
@@ -7073,7 +7179,9 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
7073
7179
  if (ev.endDate) {
7074
7180
  const y2 = yScale(parseTimelineDate(ev.endDate));
7075
7181
  const rectH = Math.max(y2 - y, 4);
7076
- let fill2 = shapeFill(palette, color, isDark, { solid });
7182
+ let fill2 = shapeFill(palette, color, isDark, {
7183
+ mode: fillMode
7184
+ });
7077
7185
  let stroke2 = color;
7078
7186
  if (ev.uncertain) {
7079
7187
  const gradientId = `uncertain-v-${ev.lineNumber}`;
@@ -7084,7 +7192,10 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
7084
7192
  { offset: "0%", opacity: 1 },
7085
7193
  { offset: "80%", opacity: 1 },
7086
7194
  { offset: "100%", opacity: 0 }
7087
- ]).enter().append("stop").attr("offset", (d) => d.offset).attr("stop-color", mix(color, bg, 30)).attr("stop-opacity", (d) => d.opacity);
7195
+ ]).enter().append("stop").attr("offset", (d) => d.offset).attr(
7196
+ "stop-color",
7197
+ fillMode === "outline" ? bg : mix(color, bg, 30)
7198
+ ).attr("stop-opacity", (d) => d.opacity);
7088
7199
  defsEl.append("linearGradient").attr("id", strokeGradientId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%").selectAll("stop").data([
7089
7200
  { offset: "0%", opacity: 1 },
7090
7201
  { offset: "80%", opacity: 1 },
@@ -7096,7 +7207,7 @@ function renderTimelineVertical(container, parsed, palette, isDark, setup, hover
7096
7207
  evG.append("rect").attr("x", axisX - sBarW / 2).attr("y", y).attr("width", sBarW).attr("height", rectH).attr("rx", sBarRx).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sBarStroke);
7097
7208
  evG.append("text").attr("x", axisX + sBarW + ctx.aesthetic(4)).attr("y", y + rectH / 2).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", `${sEventFontSm}px`).text(ev.label);
7098
7209
  } else {
7099
- evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, color, isDark, { solid })).attr("stroke", color).attr("stroke-width", sPointStroke);
7210
+ evG.append("circle").attr("cx", axisX).attr("cy", y).attr("r", sPointR).attr("fill", shapeFill(palette, color, isDark, { mode: fillMode })).attr("stroke", color).attr("stroke-width", sPointStroke);
7100
7211
  evG.append("text").attr("x", axisX + sBarW + ctx.aesthetic(4)).attr("y", y).attr("dy", "0.35em").attr("fill", textColor).attr("font-size", `${sEventFontSm}px`).text(ev.label);
7101
7212
  }
7102
7213
  evG.append("text").attr("x", axisX - ctx.aesthetic(14)).attr(
@@ -8219,7 +8330,7 @@ function parseSequenceDgmo(content, palette) {
8219
8330
  continue;
8220
8331
  }
8221
8332
  }
8222
- if (KNOWN_SEQ_BOOLEANS.has(optLower) && (optLower === "solid-fill" || optLower === "no-title")) {
8333
+ if (KNOWN_SEQ_BOOLEANS.has(optLower)) {
8223
8334
  if (contentStarted) {
8224
8335
  pushError(
8225
8336
  lineNumber,
@@ -8227,6 +8338,10 @@ function parseSequenceDgmo(content, palette) {
8227
8338
  );
8228
8339
  continue;
8229
8340
  }
8341
+ if (FILL_FAMILY_TOKENS.has(optLower)) {
8342
+ for (const t of FILL_FAMILY_TOKENS) delete result.options[t];
8343
+ if (optLower === "fill-tint") continue;
8344
+ }
8230
8345
  result.options[optLower] = "on";
8231
8346
  continue;
8232
8347
  }
@@ -8696,7 +8811,12 @@ var init_parser7 = __esm({
8696
8811
  init_reserved_key_registry();
8697
8812
  init_tag_groups();
8698
8813
  KNOWN_SEQ_OPTIONS = /* @__PURE__ */ new Set(["active-tag"]);
8699
- KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set(["solid-fill", "no-title"]);
8814
+ KNOWN_SEQ_BOOLEANS = /* @__PURE__ */ new Set([
8815
+ "fill-tint",
8816
+ "fill-solid",
8817
+ "fill-outline",
8818
+ "no-title"
8819
+ ]);
8700
8820
  NO_PREFIX_ONLY_BOOLEANS = /* @__PURE__ */ new Set(["activations"]);
8701
8821
  VALID_PARTICIPANT_TYPES = /* @__PURE__ */ new Set([
8702
8822
  "database",
@@ -9797,8 +9917,10 @@ function parseFlowchart(content, palette) {
9797
9917
  result.direction = dirMatch[1].toUpperCase();
9798
9918
  continue;
9799
9919
  }
9800
- if (/^solid-fill$/i.test(trimmed)) {
9801
- options["solid-fill"] = "on";
9920
+ if (FILL_FAMILY_TOKENS.has(trimmed.toLowerCase())) {
9921
+ for (const t of FILL_FAMILY_TOKENS) delete options[t];
9922
+ if (trimmed.toLowerCase() !== "fill-tint")
9923
+ options[trimmed.toLowerCase()] = "on";
9802
9924
  continue;
9803
9925
  }
9804
9926
  if (/^no-color$/i.test(trimmed)) {
@@ -10133,8 +10255,10 @@ function parseState(content, palette) {
10133
10255
  result.direction = "TB";
10134
10256
  continue;
10135
10257
  }
10136
- if (/^solid-fill$/i.test(trimmed)) {
10137
- options["solid-fill"] = "on";
10258
+ if (FILL_FAMILY_TOKENS.has(trimmed.toLowerCase())) {
10259
+ for (const t of FILL_FAMILY_TOKENS) delete options[t];
10260
+ if (trimmed.toLowerCase() !== "fill-tint")
10261
+ options[trimmed.toLowerCase()] = "on";
10138
10262
  continue;
10139
10263
  }
10140
10264
  if (/^no-color$/i.test(trimmed)) {
@@ -11547,7 +11671,9 @@ var init_parser10 = __esm({
11547
11671
  KNOWN_BOOLEANS = /* @__PURE__ */ new Set([
11548
11672
  "show-sub-node-count",
11549
11673
  "direction-tb",
11550
- "solid-fill",
11674
+ "fill-tint",
11675
+ "fill-solid",
11676
+ "fill-outline",
11551
11677
  "no-title"
11552
11678
  ]);
11553
11679
  }
@@ -13236,8 +13362,16 @@ function applyDirective(key, value, lineNumber, options, error, warn, dateCfg) {
13236
13362
  options.noTitle = true;
13237
13363
  return;
13238
13364
  }
13239
- case "solid-fill": {
13240
- options.solidFill = true;
13365
+ case "fill-solid": {
13366
+ options.fillMode = "solid";
13367
+ return;
13368
+ }
13369
+ case "fill-outline": {
13370
+ options.fillMode = "outline";
13371
+ return;
13372
+ }
13373
+ case "fill-tint": {
13374
+ delete options.fillMode;
13241
13375
  return;
13242
13376
  }
13243
13377
  case "active-tag": {
@@ -13485,7 +13619,9 @@ var init_parser12 = __esm({
13485
13619
  "start-date",
13486
13620
  "end-date",
13487
13621
  "no-title",
13488
- "solid-fill",
13622
+ "fill-tint",
13623
+ "fill-solid",
13624
+ "fill-outline",
13489
13625
  "sprint-length",
13490
13626
  "sprint-number",
13491
13627
  "sprint-start",
@@ -13903,8 +14039,10 @@ function parseChart(content, palette) {
13903
14039
  if (KNOWN_BOOLEANS2.has(firstToken) && spaceIdx < 0) {
13904
14040
  if (firstToken === "orientation-horizontal") {
13905
14041
  result.orientation = "horizontal";
13906
- } else if (firstToken === "solid-fill") {
13907
- result.solidFill = true;
14042
+ } else if (fillModeFromToken(firstToken) !== null) {
14043
+ const fm = fillModeFromToken(firstToken);
14044
+ if (fm === "tint") delete result.fillMode;
14045
+ else result.fillMode = fm;
13908
14046
  } else if (firstToken === "no-title") {
13909
14047
  result.noTitle = true;
13910
14048
  } else if (firstToken === "no-auto-y") {
@@ -14201,7 +14339,9 @@ var init_chart = __esm({
14201
14339
  DEFAULT_HOLE = 0.6;
14202
14340
  KNOWN_BOOLEANS2 = /* @__PURE__ */ new Set([
14203
14341
  "orientation-horizontal",
14204
- "solid-fill",
14342
+ "fill-tint",
14343
+ "fill-solid",
14344
+ "fill-outline",
14205
14345
  "no-title",
14206
14346
  "no-auto-y",
14207
14347
  "fill",
@@ -14448,7 +14588,7 @@ function parseExtendedChartFull(content, palette) {
14448
14588
  const spaceIdx2 = trimmed.indexOf(" ");
14449
14589
  const lastTok = trimmed.substring(trimmed.lastIndexOf(" ") + 1);
14450
14590
  const hasNumericSuffix = spaceIdx2 >= 0 && !isNaN(parseFloat(normalizeNumericToken(lastTok) ?? lastTok));
14451
- const isBareKeywordOption = spaceIdx2 < 0 && /^(solid-fill|no-name|no-value|no-percent|shade|no-title)$/i.test(
14591
+ const isBareKeywordOption = spaceIdx2 < 0 && /^(fill-tint|fill-solid|fill-outline|no-name|no-value|no-percent|shade|no-title)$/i.test(
14452
14592
  trimmed
14453
14593
  );
14454
14594
  const isLayoutDirective = spaceIdx2 >= 0 && trimmed.substring(0, spaceIdx2).toLowerCase() === "layout";
@@ -14579,8 +14719,10 @@ function parseExtendedChartFull(content, palette) {
14579
14719
  result.shade = true;
14580
14720
  continue;
14581
14721
  }
14582
- if (firstToken === "solid-fill") {
14583
- result.solidFill = true;
14722
+ const fillFamily = fillModeFromToken(firstToken);
14723
+ if (fillFamily !== null && spaceIdx < 0) {
14724
+ if (fillFamily === "tint") delete result.fillMode;
14725
+ else result.fillMode = fillFamily;
14584
14726
  continue;
14585
14727
  }
14586
14728
  if (firstToken === "no-title" && spaceIdx < 0) {
@@ -14933,7 +15075,7 @@ function parseEventLine(content, palette) {
14933
15075
  noTitle: false,
14934
15076
  noBox: false,
14935
15077
  noLegend: false,
14936
- solidFill: false
15078
+ fillMode: void 0
14937
15079
  };
14938
15080
  const result = {
14939
15081
  type: "event-line",
@@ -15129,9 +15271,12 @@ function parseEventLine(content, palette) {
15129
15271
  options.noLegend = true;
15130
15272
  continue;
15131
15273
  }
15132
- if (trimmed.toLowerCase() === "solid-fill") {
15133
- options.solidFill = true;
15134
- continue;
15274
+ {
15275
+ const fm = fillModeFromToken(trimmed);
15276
+ if (fm !== null) {
15277
+ options.fillMode = fm === "tint" ? void 0 : fm;
15278
+ continue;
15279
+ }
15135
15280
  }
15136
15281
  const dirMatch = trimmed.match(DIRECTION_RE);
15137
15282
  if (dirMatch) {
@@ -16267,7 +16412,12 @@ var init_parser15 = __esm({
16267
16412
  PALETTE_COLOR_WORD_RE = /^(red|orange|yellow|green|blue|purple|teal|cyan|gray|black|white)\b/;
16268
16413
  AS_ALIAS_TOKEN_RE = /^as\s+([A-Za-z][A-Za-z0-9_]{0,11})\b/;
16269
16414
  KNOWN_OPTIONS4 = /* @__PURE__ */ new Set(["hide", "active-tag", "lane-by"]);
16270
- KNOWN_BOOLEANS3 = /* @__PURE__ */ new Set(["solid-fill", "no-title"]);
16415
+ KNOWN_BOOLEANS3 = /* @__PURE__ */ new Set([
16416
+ "fill-tint",
16417
+ "fill-solid",
16418
+ "fill-outline",
16419
+ "no-title"
16420
+ ]);
16271
16421
  REMOVED_BOOLEANS = {
16272
16422
  "no-auto-color": '"no-auto-color" was removed \u2014 colors are always auto-assigned from the palette; delete this line.'
16273
16423
  };
@@ -17034,7 +17184,9 @@ var init_parser16 = __esm({
17034
17184
  KNOWN_C4_OPTIONS = /* @__PURE__ */ new Set(["layout", "active-tag"]);
17035
17185
  KNOWN_C4_BOOLEANS = /* @__PURE__ */ new Set([
17036
17186
  "direction-tb",
17037
- "solid-fill",
17187
+ "fill-tint",
17188
+ "fill-solid",
17189
+ "fill-outline",
17038
17190
  "no-title"
17039
17191
  ]);
17040
17192
  ALL_CHART_TYPES2 = [
@@ -17134,7 +17286,9 @@ var init_directives_registry = __esm({
17134
17286
  { token: "sprint-length", category: "directive", gantt: ["option"] },
17135
17287
  { token: "sprint-number", category: "directive", gantt: ["option"] },
17136
17288
  { token: "sprint-start", category: "directive", gantt: ["option"] },
17137
- { token: "solid-fill", category: "directive", gantt: ["boolean"] },
17289
+ { token: "fill-tint", category: "directive", gantt: ["boolean"] },
17290
+ { token: "fill-solid", category: "directive", gantt: ["boolean"] },
17291
+ { token: "fill-outline", category: "directive", gantt: ["boolean"] },
17138
17292
  // `chart` is a wireframe element keyword (CONTROL); gantt also accepts it as
17139
17293
  // an option. Highlight family is control.
17140
17294
  { token: "chart", category: "control", gantt: ["option"] },
@@ -18377,7 +18531,7 @@ function parseGantt(content, palette) {
18377
18531
  sprintNumber: null,
18378
18532
  sprintStart: null,
18379
18533
  sprintMode: null,
18380
- solidFill: false,
18534
+ fillMode: void 0,
18381
18535
  noTitle: false
18382
18536
  },
18383
18537
  diagnostics,
@@ -19020,8 +19174,14 @@ function parseGantt(content, palette) {
19020
19174
  case "today-marker":
19021
19175
  result.options.todayMarker = "on";
19022
19176
  break;
19023
- case "solid-fill":
19024
- result.options.solidFill = true;
19177
+ case "fill-solid":
19178
+ result.options.fillMode = "solid";
19179
+ break;
19180
+ case "fill-outline":
19181
+ result.options.fillMode = "outline";
19182
+ break;
19183
+ case "fill-tint":
19184
+ result.options.fillMode = void 0;
19025
19185
  break;
19026
19186
  case "no-title":
19027
19187
  result.options.noTitle = true;
@@ -21026,7 +21186,8 @@ var init_diagnostics6 = __esm({
21026
21186
  NESTED_BOX: "E_SKETCH_NESTED_BOX",
21027
21187
  AMBIGUOUS_TARGET: "E_SKETCH_AMBIGUOUS_TARGET",
21028
21188
  UNKNOWN_SHAPE: "W_SKETCH_UNKNOWN_SHAPE",
21029
- OVERLAP_RESOLVED: "W_SKETCH_OVERLAP_RESOLVED"
21189
+ OVERLAP_RESOLVED: "W_SKETCH_OVERLAP_RESOLVED",
21190
+ AT_OUT_OF_RANGE: "W_SKETCH_AT_OUT_OF_RANGE"
21030
21191
  };
21031
21192
  SKETCH_DIAGNOSTICS = [
21032
21193
  {
@@ -21064,6 +21225,15 @@ var init_diagnostics6 = __esm({
21064
21225
  message: (p) => `Shape "${String(p.label ?? "?")}" overlapped another at its authored position \u2014 moved to the nearest free slot`,
21065
21226
  hint: "Keep shapes at least 2 half-slots apart on one axis, or omit at: to flow-place.",
21066
21227
  example: "sketch\nA at: 0 0\nB at: 0 0"
21228
+ },
21229
+ {
21230
+ code: SKETCH_DIAGNOSTIC_CODES.AT_OUT_OF_RANGE,
21231
+ severity: "warning",
21232
+ chartType: "sketch",
21233
+ title: "at: coordinate out of range",
21234
+ message: (p) => `at: coordinate "${String(p.raw ?? "?")}" is out of range \u2014 half-slot coords must be whole numbers within \xB1${String(p.max ?? "?")}; shape will flow-place`,
21235
+ hint: "Use small integer half-slot coordinates near the origin, or omit at: to flow-place.",
21236
+ example: "sketch\nA at: 2 0"
21067
21237
  }
21068
21238
  ];
21069
21239
  }
@@ -21096,7 +21266,7 @@ __export(parser_exports15, {
21096
21266
  function parseSketch(content, palette) {
21097
21267
  const options = {
21098
21268
  noLegend: false,
21099
- solidFill: false,
21269
+ fillMode: void 0,
21100
21270
  noDescriptions: false
21101
21271
  };
21102
21272
  const result = {
@@ -21142,7 +21312,17 @@ function parseSketch(content, palette) {
21142
21312
  );
21143
21313
  return null;
21144
21314
  }
21145
- return { c: parseInt(m[1], 10), r: parseInt(m[2], 10) };
21315
+ const c = parseInt(m[1], 10);
21316
+ const r = parseInt(m[2], 10);
21317
+ if (!Number.isSafeInteger(c) || !Number.isSafeInteger(r) || Math.abs(c) > SKETCH_AT_MAX || Math.abs(r) > SKETCH_AT_MAX) {
21318
+ warn(
21319
+ lineNumber,
21320
+ `at: coordinate "${raw}" is out of range \u2014 half-slot coords must be whole numbers within \xB1${SKETCH_AT_MAX}; shape will flow-place`,
21321
+ SKETCH_DIAGNOSTIC_CODES.AT_OUT_OF_RANGE
21322
+ );
21323
+ return null;
21324
+ }
21325
+ return { c, r };
21146
21326
  };
21147
21327
  const liftReserved = (meta, lineNumber) => {
21148
21328
  let shape = "rectangle";
@@ -21470,8 +21650,9 @@ function parseSketch(content, palette) {
21470
21650
  options.noLegend = true;
21471
21651
  continue;
21472
21652
  }
21473
- if (indent === 0 && /^solid-fill\s*$/i.test(trimmed)) {
21474
- options.solidFill = true;
21653
+ if (indent === 0 && fillModeFromToken(trimmed) !== null) {
21654
+ const fm = fillModeFromToken(trimmed);
21655
+ options.fillMode = fm === "tint" ? void 0 : fm;
21475
21656
  continue;
21476
21657
  }
21477
21658
  if (indent === 0 && /^no-descriptions\s*$/i.test(trimmed)) {
@@ -21632,7 +21813,7 @@ ${descLine}`;
21632
21813
  }
21633
21814
  return result;
21634
21815
  }
21635
- var EDGE_FORMS, EDGE_START_RE, LEFT_ARROW_RE, BOX_RE, BOX_TAIL_ALIAS_RE, AT_VALUE_RE;
21816
+ var EDGE_FORMS, EDGE_START_RE, LEFT_ARROW_RE, BOX_RE, BOX_TAIL_ALIAS_RE, AT_VALUE_RE, SKETCH_AT_MAX;
21636
21817
  var init_parser21 = __esm({
21637
21818
  "src/sketch/parser.ts"() {
21638
21819
  "use strict";
@@ -21663,6 +21844,7 @@ var init_parser21 = __esm({
21663
21844
  BOX_RE = /^\[([^\]]*)\]\s*(.*)$/;
21664
21845
  BOX_TAIL_ALIAS_RE = /^as\s+([A-Za-z][A-Za-z0-9_]{0,11})(?=\s|,|$)\s*,?\s*/;
21665
21846
  AT_VALUE_RE = /^(-?\d+)\s+(-?\d+)$/;
21847
+ SKETCH_AT_MAX = 2e3;
21666
21848
  }
21667
21849
  });
21668
21850
 
@@ -21957,8 +22139,10 @@ function parseSwimlane(content, palette) {
21957
22139
  continue;
21958
22140
  }
21959
22141
  if (indent === 0) currentTagGroup = null;
21960
- if (indent === 0 && /^solid-fill\s*$/i.test(trimmed)) {
21961
- options["solid-fill"] = "on";
22142
+ if (indent === 0 && FILL_FAMILY_TOKENS.has(trimmed.toLowerCase())) {
22143
+ for (const t of FILL_FAMILY_TOKENS) delete options[t];
22144
+ if (trimmed.toLowerCase() !== "fill-tint")
22145
+ options[trimmed.toLowerCase()] = "on";
21962
22146
  continue;
21963
22147
  }
21964
22148
  if (indent === 0 && /^direction\s+/i.test(trimmed)) {
@@ -22184,7 +22368,7 @@ function parseSwimlane(content, palette) {
22184
22368
  if (!trimmed) continue;
22185
22369
  const indent = measureIndent(raw);
22186
22370
  if (indent === 0 && /^direction\s+/i.test(trimmed)) continue;
22187
- if (indent === 0 && /^solid-fill\s*$/i.test(trimmed)) continue;
22371
+ if (indent === 0 && FILL_FAMILY_TOKENS.has(trimmed.toLowerCase())) continue;
22188
22372
  if (matchTagBlockHeading(trimmed) && indent === 0) {
22189
22373
  inTagBlock = true;
22190
22374
  continue;
@@ -24382,7 +24566,9 @@ var init_parser26 = __esm({
24382
24566
  KNOWN_OPTIONS8 = /* @__PURE__ */ new Set([]);
24383
24567
  KNOWN_BOOLEANS5 = /* @__PURE__ */ new Set([
24384
24568
  "show-blip-legend",
24385
- "solid-fill",
24569
+ "fill-tint",
24570
+ "fill-solid",
24571
+ "fill-outline",
24386
24572
  "no-title"
24387
24573
  ]);
24388
24574
  }
@@ -25044,7 +25230,12 @@ var init_parser28 = __esm({
25044
25230
  PHASE_RE = /^\[(.+?)\]$/;
25045
25231
  ANNOTATION_RE = /^(pain|opportunity|thought)\s*:\s*(.+)$/i;
25046
25232
  KNOWN_OPTIONS9 = /* @__PURE__ */ new Set(["active-tag"]);
25047
- KNOWN_BOOLEANS6 = /* @__PURE__ */ new Set(["solid-fill", "no-title"]);
25233
+ KNOWN_BOOLEANS6 = /* @__PURE__ */ new Set([
25234
+ "fill-tint",
25235
+ "fill-solid",
25236
+ "fill-outline",
25237
+ "no-title"
25238
+ ]);
25048
25239
  REMOVED_BOOLEANS2 = {
25049
25240
  "no-legend": '"no-legend" has been removed \u2014 remove tag groups to hide the legend.'
25050
25241
  };
@@ -25390,7 +25581,7 @@ function parseTreemap(content, palette) {
25390
25581
  noPercent: false,
25391
25582
  noHeaders: false,
25392
25583
  noLegend: false,
25393
- solidFill: false,
25584
+ fillMode: void 0,
25394
25585
  radial: false
25395
25586
  };
25396
25587
  const result = {
@@ -25607,9 +25798,12 @@ function handleDirective(trimmed, options, result, pushWarning, lineNumber) {
25607
25798
  else if (key === "legend") options.noLegend = true;
25608
25799
  return true;
25609
25800
  }
25610
- if (/^solid-fill\s*$/i.test(trimmed)) {
25611
- options.solidFill = true;
25612
- return true;
25801
+ {
25802
+ const fm = fillModeFromToken(trimmed);
25803
+ if (fm !== null) {
25804
+ options.fillMode = fm === "tint" ? void 0 : fm;
25805
+ return true;
25806
+ }
25613
25807
  }
25614
25808
  if (/^radial\s*$/i.test(trimmed)) {
25615
25809
  options.radial = true;
@@ -25720,7 +25914,7 @@ __export(parser_exports26, {
25720
25914
  parseBlock: () => parseBlock
25721
25915
  });
25722
25916
  function parseBlock(content, palette) {
25723
- const options = { noLegend: false, solidFill: false };
25917
+ const options = { noLegend: false };
25724
25918
  const result = {
25725
25919
  type: "block",
25726
25920
  title: null,
@@ -25828,8 +26022,10 @@ function parseBlock(content, palette) {
25828
26022
  options.noLegend = true;
25829
26023
  continue;
25830
26024
  }
25831
- if (/^solid-fill\s*$/i.test(trimmed)) {
25832
- options.solidFill = true;
26025
+ const fm = fillModeFromToken(trimmed);
26026
+ if (fm !== null) {
26027
+ if (fm === "tint") delete options.fillMode;
26028
+ else options.fillMode = fm;
25833
26029
  continue;
25834
26030
  }
25835
26031
  }
@@ -26051,7 +26247,7 @@ function parseGoal(content, palette) {
26051
26247
  const options = {
26052
26248
  noPercent: false,
26053
26249
  noValue: false,
26054
- solidFill: false,
26250
+ fillMode: void 0,
26055
26251
  noTitle: false,
26056
26252
  noAutoColor: false,
26057
26253
  noNote: false
@@ -26145,7 +26341,7 @@ function parseGoal(content, palette) {
26145
26341
  continue;
26146
26342
  }
26147
26343
  if (tryParseSharedOption(trimmed, sharedOpts)) {
26148
- if (sharedOpts["solid-fill"] === "on") options.solidFill = true;
26344
+ options.fillMode = fillModeFromOptions(sharedOpts);
26149
26345
  if (sharedOpts["no-title"] === "on") options.noTitle = true;
26150
26346
  continue;
26151
26347
  }
@@ -26903,6 +27099,16 @@ function parseCountdown(content, palette) {
26903
27099
  case "no-visual":
26904
27100
  result.noVisual = true;
26905
27101
  break;
27102
+ // ── §1.9 fill family — mutually exclusive bare flags, last one wins;
27103
+ // `fill-tint` is the explicit spelling of the default (clears it). ──
27104
+ case "fill-tint":
27105
+ case "fill-solid":
27106
+ case "fill-outline": {
27107
+ const fm = fillModeFromToken(key);
27108
+ if (fm === "solid" || fm === "outline") result.fillMode = fm;
27109
+ else delete result.fillMode;
27110
+ break;
27111
+ }
26906
27112
  // ── `note` — markdown caption; inline value or indented body block. ──
26907
27113
  case "note":
26908
27114
  inNote = true;
@@ -27790,6 +27996,14 @@ function parseClock(content, palette) {
27790
27996
  case "no-title":
27791
27997
  result.noTitle = true;
27792
27998
  break;
27999
+ case "fill-tint":
28000
+ case "fill-solid":
28001
+ case "fill-outline": {
28002
+ const fm = fillModeFromToken(key);
28003
+ if (fm === "solid" || fm === "outline") result.fillMode = fm;
28004
+ else delete result.fillMode;
28005
+ break;
28006
+ }
27793
28007
  case "color-by": {
27794
28008
  const v = rest.trim().toLowerCase();
27795
28009
  const modes = ["place", "work", "daylight", "time", "none"];
@@ -27950,7 +28164,10 @@ var init_parser35 = __esm({
27950
28164
  "time-24",
27951
28165
  "no-title",
27952
28166
  "direction",
27953
- "color-by"
28167
+ "color-by",
28168
+ "fill-tint",
28169
+ "fill-solid",
28170
+ "fill-outline"
27954
28171
  ]);
27955
28172
  WEEKDAY_ABBR2 = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
27956
28173
  }
@@ -28150,6 +28367,12 @@ function parseBracket(content, palette) {
28150
28367
  result.noRounds = true;
28151
28368
  continue;
28152
28369
  }
28370
+ const fm = fillModeFromToken(lower);
28371
+ if (fm !== null) {
28372
+ if (fm === "tint") delete result.fillMode;
28373
+ else result.fillMode = fm;
28374
+ continue;
28375
+ }
28153
28376
  const accentM = trimmed.match(/^accent\s+(.+)$/i);
28154
28377
  if (accentM) {
28155
28378
  const { color } = extractColor(
@@ -31793,6 +32016,13 @@ function parseBody(content, palette) {
31793
32016
  options.noTitle = true;
31794
32017
  continue;
31795
32018
  }
32019
+ const fm = fillModeFromToken(trimmed);
32020
+ if (fm !== null) {
32021
+ if (fm === "tint") delete options.fillMode;
32022
+ else options.fillMode = fm;
32023
+ currentTagGroup = null;
32024
+ continue;
32025
+ }
31796
32026
  }
31797
32027
  const tagBlockMatch = matchTagBlockHeading(trimmed);
31798
32028
  if (tagBlockMatch && !contentStarted) {
@@ -32732,12 +32962,12 @@ function renderBar(svg, chart, width, height, colors, palette, isDark, textColor
32732
32962
  ) : 1;
32733
32963
  const horizontal = chart.orientation === "horizontal";
32734
32964
  const multiSeries = seriesCount > 1;
32735
- const solid = chart.solidFill === true;
32965
+ const fillMode = chart.fillMode;
32736
32966
  const colorFor = (seriesIdx, catIdx, override) => {
32737
32967
  if (override) return override;
32738
32968
  return multiSeries ? colors[seriesIdx % colors.length] : colors[catIdx % colors.length];
32739
32969
  };
32740
- const fillOf = (c) => solid ? c : shapeFill(palette, c, isDark);
32970
+ const fillOf = (c) => shapeFill(palette, c, isDark, { mode: fillMode });
32741
32971
  const top = reserveHeader(
32742
32972
  svg,
32743
32973
  chart,
@@ -32922,7 +33152,7 @@ function seriesValue(pt, s) {
32922
33152
  function renderLine(svg, chart, width, height, colors, palette, isDark, textColor, mutedColor, bgColor, hasTitle) {
32923
33153
  const data = chart.data;
32924
33154
  const isArea = chart.fill === true;
32925
- const solid = chart.solidFill === true;
33155
+ const solid = chart.fillMode === "solid";
32926
33156
  const seriesNames = chart.seriesNames?.length ? chart.seriesNames : [chart.series ?? ""];
32927
33157
  const seriesCount = Math.max(
32928
33158
  1,
@@ -33085,7 +33315,7 @@ function renderPie(svg, chart, width, height, palette, isDark, textColor, topIns
33085
33315
  if (data.length === 0) return;
33086
33316
  const holeRatio = chart.hole;
33087
33317
  const hasHole = holeRatio !== void 0;
33088
- const solid = chart.solidFill === true;
33318
+ const fillMode = chart.fillMode;
33089
33319
  const total = data.reduce((a, d) => a + d.value, 0);
33090
33320
  const cx = width / 2;
33091
33321
  const top = topInset + 12;
@@ -33120,7 +33350,7 @@ function renderPie(svg, chart, width, height, palette, isDark, textColor, topIns
33120
33350
  const g = svg.append("g").attr("transform", `translate(${cx},${cy})`);
33121
33351
  arcs.forEach((a, i) => {
33122
33352
  const stroke2 = strokeFor(i, data[i].color);
33123
- const fill2 = solid ? stroke2 : shapeFill(palette, stroke2, isDark);
33353
+ const fill2 = shapeFill(palette, stroke2, isDark, { mode: fillMode });
33124
33354
  const pct = Math.round(data[i].value / total * 100);
33125
33355
  const slice = g.append("path").attr("d", arcGen(a) ?? "").attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.5);
33126
33356
  tagDatum(slice, {
@@ -33180,7 +33410,8 @@ function renderRadar(svg, chart, width, height, colors, palette, isDark, textCol
33180
33410
  const data = chart.data;
33181
33411
  const n = data.length;
33182
33412
  if (n < 3) return;
33183
- const solid = chart.solidFill === true;
33413
+ const fillMode = chart.fillMode;
33414
+ const solid = fillMode === "solid";
33184
33415
  const seriesNames = chart.seriesNames?.length ? chart.seriesNames : [chart.series ?? ""];
33185
33416
  const seriesCount = Math.max(
33186
33417
  1,
@@ -33224,7 +33455,10 @@ function renderRadar(svg, chart, width, height, colors, palette, isDark, textCol
33224
33455
  const seriesLine = chart.seriesNameLineNumbers?.[s];
33225
33456
  if (seriesLine !== void 0) g.attr("data-line-number", seriesLine);
33226
33457
  const poly = data.map((d, i) => pt(i, seriesValue2(d, s) / maxValue * radius).join(",")).join(" ");
33227
- g.append("polygon").attr("points", poly).attr("fill", solid || multi ? color : shapeFill(palette, color, isDark)).attr("fill-opacity", solid ? 0.6 : multi ? 0.2 : 1).attr("stroke", color).attr("stroke-width", 2);
33458
+ g.append("polygon").attr("points", poly).attr(
33459
+ "fill",
33460
+ fillMode === "outline" ? "none" : solid || multi ? color : shapeFill(palette, color, isDark)
33461
+ ).attr("fill-opacity", solid ? 0.6 : multi ? 0.2 : 1).attr("stroke", color).attr("stroke-width", 2);
33228
33462
  data.forEach((d, i) => {
33229
33463
  const v = seriesValue2(d, s);
33230
33464
  const [x, y] = pt(i, v / maxValue * radius);
@@ -33265,7 +33499,7 @@ function renderPolarArea(svg, chart, width, height, palette, isDark, textColor,
33265
33499
  const data = chart.data.filter((d) => d.value > 0);
33266
33500
  const n = data.length;
33267
33501
  if (n === 0) return;
33268
- const solid = chart.solidFill === true;
33502
+ const fillMode = chart.fillMode;
33269
33503
  const total = data.reduce((a, d) => a + d.value, 0);
33270
33504
  const maxValue = Math.max(...data.map((d) => d.value)) || 1;
33271
33505
  const cx = width / 2;
@@ -33283,7 +33517,7 @@ function renderPolarArea(svg, chart, width, height, palette, isDark, textColor,
33283
33517
  const a1 = a0 + seg;
33284
33518
  const arcGen = d3arc2().innerRadius(innerR).outerRadius(r).startAngle(a0).endAngle(a1);
33285
33519
  const pct = Math.round(d.value / total * 100);
33286
- const sector = g.append("path").attr("d", arcGen({}) ?? "").attr("fill", solid ? stroke2 : shapeFill(palette, stroke2, isDark)).attr("stroke", stroke2).attr("stroke-width", 2);
33520
+ const sector = g.append("path").attr("d", arcGen({}) ?? "").attr("fill", shapeFill(palette, stroke2, isDark, { mode: fillMode })).attr("stroke", stroke2).attr("stroke-width", 2);
33287
33521
  tagDatum(sector, {
33288
33522
  line: d.lineNumber,
33289
33523
  key: d.label,
@@ -33320,7 +33554,7 @@ function renderFunnel(svg, chart, width, height, colors, palette, isDark, topIns
33320
33554
  const sorted = [...chart.data].sort((a, b) => b.value - a.value);
33321
33555
  const n = sorted.length;
33322
33556
  if (n === 0) return;
33323
- const solid = chart.solidFill === true;
33557
+ const fillMode = chart.fillMode;
33324
33558
  const top = topInset + 8;
33325
33559
  const bottom = height - 30;
33326
33560
  const H2 = bottom - top;
@@ -33378,7 +33612,7 @@ function renderFunnel(svg, chart, width, height, colors, palette, isDark, topIns
33378
33612
  ({ plotW, cx } = layout(rightW));
33379
33613
  sorted.forEach((d, i) => {
33380
33614
  const stroke2 = d.color ?? colors[chart.data.indexOf(d) % colors.length];
33381
- const fill2 = solid ? stroke2 : shapeFill(palette, stroke2, isDark);
33615
+ const fill2 = shapeFill(palette, stroke2, isDark, { mode: fillMode });
33382
33616
  const { topW, botW } = bandWidthsAt(plotW, i);
33383
33617
  const y0 = top + i * bandH;
33384
33618
  const y1 = y0 + bandH;
@@ -33402,7 +33636,7 @@ function renderFunnel(svg, chart, width, height, colors, palette, isDark, topIns
33402
33636
  const valueInside = valueInsideAt(plotW, i);
33403
33637
  if (valueInside) {
33404
33638
  const valueSize = valueSizeAt(plotW, i);
33405
- const valueFill = solid ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : stroke2;
33639
+ const valueFill = fillMode === "solid" ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : stroke2;
33406
33640
  svg.append("text").attr("x", cx).attr("y", yMid + valueSize * 0.35).attr("text-anchor", "middle").attr("fill", valueFill).attr("font-size", valueSize).attr("font-weight", 700).attr("font-family", FONT_FAMILY).text(fmtNum(d.value));
33407
33641
  }
33408
33642
  const showValueRight = !chart.noValue && !valueInside;
@@ -33446,12 +33680,14 @@ function renderHeatmap(svg, chart, width, height, palette, isDark, textColor, bg
33446
33680
  minValue = Math.min(minValue, v);
33447
33681
  maxValue = Math.max(maxValue, v);
33448
33682
  }
33449
- const solid = chart.solidFill === true;
33683
+ const outline = chart.fillMode === "outline";
33684
+ const fillMode = outline || chart.fillMode === "solid" ? "solid" : void 0;
33685
+ const baseBg = themeBaseBg(palette, isDark);
33450
33686
  const gradientStops = [
33451
- shapeFill(palette, palette.primary, isDark, { solid }),
33452
- shapeFill(palette, palette.colors.cyan, isDark, { solid }),
33453
- shapeFill(palette, palette.colors.yellow, isDark, { solid }),
33454
- shapeFill(palette, palette.colors.orange, isDark, { solid })
33687
+ shapeFill(palette, palette.primary, isDark, { mode: fillMode }),
33688
+ shapeFill(palette, palette.colors.cyan, isDark, { mode: fillMode }),
33689
+ shapeFill(palette, palette.colors.yellow, isDark, { mode: fillMode }),
33690
+ shapeFill(palette, palette.colors.orange, isDark, { mode: fillMode })
33455
33691
  ];
33456
33692
  const gradientAt = (t) => {
33457
33693
  const tt = Math.max(0, Math.min(1, t));
@@ -33501,25 +33737,26 @@ function renderHeatmap(svg, chart, width, height, palette, isDark, textColor, bg
33501
33737
  svg.append("text").attr("class", "dgmo-axis-label").attr("data-filter-attr", "data-row-key").attr("data-filter-value", row.label).attr("x", left - 10).attr("y", top + ri * ch + ch / 2 + 4).attr("text-anchor", "end").attr("fill", textColor).attr("font-size", 13).attr("font-family", FONT_FAMILY).text(row.label);
33502
33738
  row.values.forEach((v, ci) => {
33503
33739
  const t = maxValue === minValue ? 0.5 : (v - minValue) / (maxValue - minValue);
33504
- const cell = gradientAt(t);
33740
+ const ramp = gradientAt(t);
33741
+ const cell = outline ? baseBg : ramp;
33505
33742
  const colLabel = cols[ci] ?? `Col ${ci + 1}`;
33506
33743
  const cellKey = `${row.label} \xB7 ${colLabel}`;
33507
- const r = svg.append("rect").attr("x", left + ci * cw).attr("y", top + ri * ch).attr("width", cw).attr("height", ch).attr("fill", cell).attr("stroke", bgColor).attr("stroke-width", 2).attr("data-row-key", row.label).attr("data-col-key", colLabel);
33744
+ const r = svg.append("rect").attr("x", left + ci * cw).attr("y", top + ri * ch).attr("width", cw).attr("height", ch).attr("fill", cell).attr("stroke", outline ? ramp : bgColor).attr("stroke-width", outline ? 1.5 : 2).attr("data-row-key", row.label).attr("data-col-key", colLabel);
33508
33745
  tagDatum(r, {
33509
33746
  line: row.lineNumber,
33510
33747
  key: cellKey,
33511
33748
  name: cellKey,
33512
33749
  value: fmtNum(v),
33513
- color: cell
33750
+ color: ramp
33514
33751
  });
33515
33752
  if (!chart.noValue) {
33516
- const label = svg.append("text").attr("x", left + ci * cw + cw / 2).attr("y", top + ri * ch + ch / 2 + cellFont / 3).attr("text-anchor", "middle").attr("fill", labelTint(cell)).attr("font-size", cellFont).attr("font-weight", 600).attr("font-family", FONT_FAMILY).text(fmtNum(v));
33753
+ const label = svg.append("text").attr("x", left + ci * cw + cw / 2).attr("y", top + ri * ch + ch / 2 + cellFont / 3).attr("text-anchor", "middle").attr("fill", labelTint(ramp)).attr("font-size", cellFont).attr("font-weight", 600).attr("font-family", FONT_FAMILY).text(fmtNum(v));
33517
33754
  tagDatum(label, {
33518
33755
  line: row.lineNumber,
33519
33756
  key: cellKey,
33520
33757
  name: cellKey,
33521
33758
  value: fmtNum(v),
33522
- color: cell
33759
+ color: ramp
33523
33760
  });
33524
33761
  label.attr("data-row-key", row.label).attr("data-col-key", colLabel);
33525
33762
  }
@@ -33593,7 +33830,7 @@ function placeScatterHoverValue(cx, cy, r, labelText, valueText, labelRects, cir
33593
33830
  function renderScatter(svg, chart, width, height, colors, palette, isDark, textColor, mutedColor, topInset) {
33594
33831
  const points = chart.scatterPoints ?? [];
33595
33832
  if (points.length === 0) return;
33596
- const solid = chart.solidFill === true;
33833
+ const fillMode = chart.fillMode;
33597
33834
  const hasSize = points.some((p) => p.size !== void 0);
33598
33835
  const categories = [
33599
33836
  ...new Set(points.map((p) => p.category).filter(Boolean))
@@ -33675,7 +33912,7 @@ function renderScatter(svg, chart, width, height, colors, palette, isDark, textC
33675
33912
  points.forEach((p, i) => {
33676
33913
  const stroke2 = p.color ?? (p.category ? catColor(p.category, catIndex.get(p.category) ?? 0) : colors[i % colors.length]);
33677
33914
  const r = radii[i];
33678
- const dot = svg.append("circle").attr("cx", x(p.x)).attr("cy", y(p.y)).attr("r", r).attr("fill", solid ? stroke2 : shapeFill(palette, stroke2, isDark)).attr("fill-opacity", FILL_OPACITY).attr("stroke", stroke2).attr("stroke-width", 2);
33915
+ const dot = svg.append("circle").attr("cx", x(p.x)).attr("cy", y(p.y)).attr("r", r).attr("fill", shapeFill(palette, stroke2, isDark, { mode: fillMode })).attr("fill-opacity", FILL_OPACITY).attr("stroke", stroke2).attr("stroke-width", 2);
33679
33916
  tagDatum(dot, {
33680
33917
  line: p.lineNumber,
33681
33918
  key: p.name,
@@ -33743,7 +33980,7 @@ var init_scatter = __esm({
33743
33980
  function renderSankey(svg, chart, width, height, colors, bgColor, textColor, topInset) {
33744
33981
  const links = chart.links ?? [];
33745
33982
  if (links.length === 0) return;
33746
- const solid = chart.solidFill === true;
33983
+ const solid = chart.fillMode === "solid";
33747
33984
  const names = Array.from(new Set(links.flatMap((l) => [l.source, l.target])));
33748
33985
  const node = /* @__PURE__ */ new Map();
33749
33986
  names.forEach(
@@ -33845,7 +34082,9 @@ function renderSankey(svg, chart, width, height, colors, bgColor, textColor, top
33845
34082
  ).attr("fill", color).attr("fill-opacity", 0.6);
33846
34083
  tagDatum(ribbon, {
33847
34084
  line: l.lineNumber,
33848
- key: `link:${s.name}\0${t.name}`,
34085
+ // U+241F (symbol-for-unit-separator) — collision-proof AND XML-legal;
34086
+ // a raw control char here corrupts the exported SVG (data-emph-key).
34087
+ key: `link:${s.name}\u241F${t.name}`,
33849
34088
  name: `${s.name} \u2192 ${t.name}`,
33850
34089
  value: String(l.value),
33851
34090
  color: s.raw
@@ -33884,7 +34123,7 @@ var init_sankey = __esm({
33884
34123
  function renderChord(svg, chart, width, height, colors, palette, isDark, textColor, topInset) {
33885
34124
  const links = chart.links ?? [];
33886
34125
  if (links.length === 0) return;
33887
- const solid = chart.solidFill === true;
34126
+ const fillMode = chart.fillMode;
33888
34127
  const names = Array.from(new Set(links.flatMap((l) => [l.source, l.target])));
33889
34128
  const n = names.length;
33890
34129
  const idx = new Map(names.map((nm, i) => [nm, i]));
@@ -33944,7 +34183,7 @@ function renderChord(svg, chart, width, height, colors, palette, isDark, textCol
33944
34183
  names.forEach((nm, i) => {
33945
34184
  const [px, py] = pos(i);
33946
34185
  const stroke2 = colorOf2(i);
33947
- const dot = svg.append("circle").attr("cx", px).attr("cy", py).attr("r", 10).attr("fill", solid ? stroke2 : shapeFill(palette, stroke2, isDark)).attr("stroke", stroke2).attr("stroke-width", 2);
34186
+ const dot = svg.append("circle").attr("cx", px).attr("cy", py).attr("r", 10).attr("fill", shapeFill(palette, stroke2, isDark, { mode: fillMode })).attr("stroke", stroke2).attr("stroke-width", 2);
33948
34187
  tagDatum(dot, { key: `node:${nm}`, name: nm, color: stroke2 });
33949
34188
  const c = Math.cos(angle(i));
33950
34189
  const lx = px + c * 16;
@@ -34489,7 +34728,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
34489
34728
  const event = slot.event;
34490
34729
  const solid2 = eventColor(event);
34491
34730
  const cardFill2 = shapeFill(palette, solid2, isDark, {
34492
- solid: parsed.options.solidFill
34731
+ mode: parsed.options.fillMode
34493
34732
  });
34494
34733
  const titleColor2 = contrastText(
34495
34734
  cardFill2,
@@ -34859,11 +35098,11 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
34859
35098
  cardG.append("clipPath").attr("id", clipId).append("rect").attr("x", 0).attr("y", shelfTop).attr("width", CARD_W).attr("height", shelfH).attr("rx", SHELF_EDGE);
34860
35099
  cardG.append("rect").attr("x", 0).attr("y", shelfTop).attr("width", CARD_W).attr("height", shelfH).attr("clip-path", `url(#${clipId})`).attr(
34861
35100
  "fill",
34862
- parsed.options.solidFill ? p.color : mix(p.color, themeBaseBg(palette, isDark), SHELF_TINT)
35101
+ parsed.options.fillMode ? p.color : mix(p.color, themeBaseBg(palette, isDark), SHELF_TINT)
34863
35102
  );
34864
35103
  const edgeY = titleNearTop ? shelfTop : shelfTop + shelfH - SHELF_EDGE;
34865
35104
  cardG.append("rect").attr("x", 0).attr("y", edgeY).attr("width", CARD_W).attr("height", SHELF_EDGE).attr("clip-path", `url(#${clipId})`).attr("fill", p.color).attr("fill-opacity", p.future ? 0.4 : 1);
34866
- const shelfText = parsed.options.solidFill ? contrastText(p.color, palette.textOnFillLight, palette.textOnFillDark) : p.color;
35105
+ const shelfText = parsed.options.fillMode ? contrastText(p.color, palette.textOnFillLight, palette.textOnFillDark) : p.color;
34867
35106
  const titleMid = headBandTop + p.headerH / 2;
34868
35107
  const titleTop = titleMid - (p.titleLines.length - 1) * TITLE_LINE_H / 2;
34869
35108
  for (let ti = 0; ti < p.titleLines.length; ti++) {
@@ -34875,7 +35114,7 @@ function renderEventLine(container, parsed, palette, isDark, onClickItem, export
34875
35114
  (titleNearTop ? p.headerH : headBandTop - dateH) + DATE_SUBTITLE_FONT + 2
34876
35115
  ).attr(
34877
35116
  "fill",
34878
- parsed.options.solidFill ? mix(shelfText, p.color, 25) : mix(palette.text, palette.bg, 55)
35117
+ parsed.options.fillMode ? mix(shelfText, p.color, 25) : mix(palette.text, palette.bg, 55)
34879
35118
  ).attr("font-family", FONT_FAMILY).attr("font-size", DATE_SUBTITLE_FONT).attr("font-weight", 600).text(dateStr);
34880
35119
  }
34881
35120
  if (p.lines.length > 0) {
@@ -35381,7 +35620,7 @@ function sideCenter(centers, side, view) {
35381
35620
  (best, c) => wantScreenRight ? c.x > best.x ? c : best : c.x < best.x ? c : best
35382
35621
  );
35383
35622
  }
35384
- function renderFigureBody(fig, view, parts, partColor, emphKey, form, palette, defs) {
35623
+ function renderFigureBody(fig, view, parts, partColor, emphKey, form, palette, isDark, fillMode, defs) {
35385
35624
  const [vx, vy, vw, vh] = fig.viewBox.split(" ").map(Number);
35386
35625
  const muscleFill = mix(palette.bg, palette.border, 0.7);
35387
35626
  const seam = palette.bg;
@@ -35429,7 +35668,16 @@ function renderFigureBody(fig, view, parts, partColor, emphKey, form, palette, d
35429
35668
  );
35430
35669
  if (sidePaths.length) paths = sidePaths;
35431
35670
  }
35432
- if (form === "skin") {
35671
+ if (fillMode === "solid") {
35672
+ for (const d of paths) {
35673
+ out += `<path${dataLine} d="${d}" fill="${color}" stroke="${color}" stroke-width="1.5"/>`;
35674
+ }
35675
+ } else if (fillMode === "outline") {
35676
+ const baseBg = themeBaseBg(palette, isDark);
35677
+ for (const d of paths) {
35678
+ out += `<path${dataLine} d="${d}" fill="${baseBg}" stroke="${color}" stroke-width="2.5"/>`;
35679
+ }
35680
+ } else if (form === "skin") {
35433
35681
  for (const d of paths) {
35434
35682
  out += `<path${dataLine} d="${d}" fill="${color}" fill-opacity="0.5" stroke="${color}" stroke-width="1.5"/>`;
35435
35683
  }
@@ -35516,6 +35764,8 @@ function renderBody2(container, parsed, palette, _isDark, _onClickItem, exportDi
35516
35764
  emphKey,
35517
35765
  parsed.options.form,
35518
35766
  palette,
35767
+ _isDark,
35768
+ parsed.options.fillMode,
35519
35769
  defs
35520
35770
  )
35521
35771
  );
@@ -37049,11 +37299,9 @@ __export(renderer_exports4, {
37049
37299
  renderOrgForExport: () => renderOrgForExport
37050
37300
  });
37051
37301
  import * as d3Selection9 from "d3-selection";
37052
- function nodeFill(palette, isDark, nodeColor2, solid) {
37302
+ function nodeFill(palette, isDark, nodeColor2, fillMode) {
37053
37303
  const color = nodeColor2 ?? palette.primary;
37054
- return shapeFill(palette, color, isDark, {
37055
- ...solid !== void 0 && { solid }
37056
- });
37304
+ return shapeFill(palette, color, isDark, { mode: fillMode });
37057
37305
  }
37058
37306
  function nodeStroke(palette, nodeColor2) {
37059
37307
  return nodeColor2 ?? palette.primary;
@@ -37257,12 +37505,12 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
37257
37505
  onClickItem(node.lineNumber);
37258
37506
  });
37259
37507
  }
37260
- const solid = parsed.options["solid-fill"] === "on";
37508
+ const fillMode = fillModeFromOptions(parsed.options);
37261
37509
  const fill2 = nodeFill(
37262
37510
  palette,
37263
37511
  isDark,
37264
37512
  colorOff ? void 0 : node.color,
37265
- solid
37513
+ fillMode
37266
37514
  );
37267
37515
  const stroke2 = nodeStroke(palette, colorOff ? void 0 : node.color);
37268
37516
  const labelColor = contrastText(
@@ -37291,7 +37539,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
37291
37539
  fontSize: sMetaFontSize,
37292
37540
  lineHeight: sMetaLineHeight,
37293
37541
  separatorGap: sSeparatorGap,
37294
- separatorColor: solid ? labelColor : stroke2,
37542
+ separatorColor: fillMode === "solid" ? labelColor : stroke2,
37295
37543
  textColor: labelColor
37296
37544
  }
37297
37545
  }
@@ -37303,7 +37551,7 @@ function renderOrg(container, parsed, layout, palette, isDark, onClickItem, expo
37303
37551
  barHeight: sCollapseBarHeight,
37304
37552
  inset: sCollapseBarInset,
37305
37553
  rx: sCardRadius,
37306
- fill: solid ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
37554
+ fill: fillMode === "solid" ? labelColor : nodeStroke(palette, colorOff ? void 0 : node.color),
37307
37555
  clipId: `clip-${node.id}`,
37308
37556
  className: "org-collapse-bar"
37309
37557
  });
@@ -37456,6 +37704,7 @@ var init_renderer5 = __esm({
37456
37704
  "src/org/renderer.ts"() {
37457
37705
  "use strict";
37458
37706
  init_tag_groups();
37707
+ init_parsing();
37459
37708
  init_fonts();
37460
37709
  init_export_container();
37461
37710
  init_scaling();
@@ -38232,11 +38481,9 @@ __export(renderer_exports5, {
38232
38481
  });
38233
38482
  import * as d3Selection10 from "d3-selection";
38234
38483
  import * as d3Shape2 from "d3-shape";
38235
- function nodeFill2(palette, isDark, nodeColor2, solid) {
38484
+ function nodeFill2(palette, isDark, nodeColor2, fillMode) {
38236
38485
  const color = nodeColor2 ?? palette.primary;
38237
- return shapeFill(palette, color, isDark, {
38238
- ...solid !== void 0 && { solid }
38239
- });
38486
+ return shapeFill(palette, color, isDark, { mode: fillMode });
38240
38487
  }
38241
38488
  function nodeStroke2(_palette, nodeColor2) {
38242
38489
  return nodeColor2 ?? _palette.primary;
@@ -38422,8 +38669,8 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
38422
38669
  const tagVal = node.tagMetadata[tagKey];
38423
38670
  if (tagVal) nodeG.attr(`data-tag-${tagKey}`, tagVal.toLowerCase());
38424
38671
  }
38425
- const solid = parsed.options["solid-fill"] === "on";
38426
- const fill2 = nodeFill2(palette, isDark, node.color, solid);
38672
+ const fillMode = fillModeFromOptions(parsed.options);
38673
+ const fill2 = nodeFill2(palette, isDark, node.color, fillMode);
38427
38674
  const stroke2 = nodeStroke2(palette, node.color);
38428
38675
  const labelColor = contrastText(
38429
38676
  fill2,
@@ -38444,7 +38691,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
38444
38691
  });
38445
38692
  const metaEntries = Object.entries(node.metadata);
38446
38693
  if (metaEntries.length > 0) {
38447
- nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3);
38694
+ nodeG.append("line").attr("x1", 0).attr("y1", sHeaderHeight).attr("x2", node.width).attr("y2", sHeaderHeight).attr("stroke", fillMode === "solid" ? labelColor : stroke2).attr("stroke-opacity", 0.3);
38448
38695
  const metaDisplayKeys = metaEntries.map(
38449
38696
  ([k]) => displayNames.get(k) ?? k
38450
38697
  );
@@ -38457,7 +38704,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
38457
38704
  const displayKey = metaDisplayKeys[i];
38458
38705
  const rowY = sHeaderHeight + sSeparatorGap + (i + 1) * sMetaLineHeight - 4;
38459
38706
  const tagColor = tagColors.get(`${key}:${value.toLowerCase()}`);
38460
- const valColor = solid ? labelColor : tagColor ?? labelColor;
38707
+ const valColor = fillMode === "solid" ? labelColor : tagColor ?? labelColor;
38461
38708
  nodeG.append("text").attr("x", 10).attr("y", rowY).attr("fill", labelColor).attr("font-size", sMetaFontSize).text(`${displayKey}:`);
38462
38709
  nodeG.append("text").attr("x", valueX).attr("y", rowY).attr("fill", valColor).attr("font-size", sMetaFontSize).text(value);
38463
38710
  }
@@ -38465,7 +38712,7 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
38465
38712
  if (node.description && node.description.length > 0) {
38466
38713
  const metaCount = Object.keys(node.metadata).length;
38467
38714
  const sepY = metaCount > 0 ? sHeaderHeight + sSeparatorGap + metaCount * sMetaLineHeight : sHeaderHeight;
38468
- nodeG.append("line").attr("x1", 0).attr("y1", sepY).attr("x2", node.width).attr("y2", sepY).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3);
38715
+ nodeG.append("line").attr("x1", 0).attr("y1", sepY).attr("x2", node.width).attr("y2", sepY).attr("stroke", fillMode === "solid" ? labelColor : stroke2).attr("stroke-opacity", 0.3);
38469
38716
  const descStartY = sHeaderHeight + sSeparatorGap + metaCount * sMetaLineHeight;
38470
38717
  for (let di = 0; di < node.description.length; di++) {
38471
38718
  const processed = preprocessDescriptionLine(node.description[di]);
@@ -38477,7 +38724,10 @@ function renderSitemap(container, parsed, layout, palette, isDark, onClickItem,
38477
38724
  if (!exportDims && node.hiddenCount && node.hiddenCount > 0) {
38478
38725
  const clipId = `clip-${node.id}`;
38479
38726
  nodeG.append("clipPath").attr("id", clipId).append("rect").attr("width", node.width).attr("height", node.height).attr("rx", CARD_RADIUS);
38480
- nodeG.append("rect").attr("y", node.height - sCollapseBarHeight).attr("width", node.width).attr("height", sCollapseBarHeight).attr("fill", solid ? labelColor : node.color ?? palette.primary).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
38727
+ nodeG.append("rect").attr("y", node.height - sCollapseBarHeight).attr("width", node.width).attr("height", sCollapseBarHeight).attr(
38728
+ "fill",
38729
+ fillMode === "solid" ? labelColor : node.color ?? palette.primary
38730
+ ).attr("opacity", 0.5).attr("clip-path", `url(#${clipId})`);
38481
38731
  }
38482
38732
  }
38483
38733
  if (exportDims && hasLegend) {
@@ -38611,6 +38861,7 @@ var init_renderer6 = __esm({
38611
38861
  "src/sitemap/renderer.ts"() {
38612
38862
  "use strict";
38613
38863
  init_tag_groups();
38864
+ init_parsing();
38614
38865
  init_fonts();
38615
38866
  init_color_utils();
38616
38867
  init_inline_markdown();
@@ -38771,7 +39022,9 @@ function renderKanban(container, parsed, palette, isDark, options) {
38771
39022
  const collapsedLanes = options?.collapsedLanes;
38772
39023
  const collapsedColumns = options?.collapsedColumns ?? new Set(parsed.columns.filter((c) => c.collapsed).map((c) => c.id));
38773
39024
  const compactMeta = options?.compactMeta ?? false;
38774
- const solid = parsed.options["solid-fill"] === "on";
39025
+ const fillMode = fillModeFromOptions(parsed.options);
39026
+ const baseBg = themeBaseBg(palette, isDark);
39027
+ const wellStroke = mix(palette.border, baseBg, 20);
38775
39028
  const requestedSwimlane = options?.currentSwimlaneGroup ?? null;
38776
39029
  const swimlaneGroup = requestedSwimlane ? parsed.tagGroups.find(
38777
39030
  (g) => g.name.toLowerCase() === requestedSwimlane.toLowerCase()
@@ -38934,20 +39187,26 @@ function renderKanban(container, parsed, palette, isDark, options) {
38934
39187
  const isColCollapsed = collapsedColumns?.has(col.id) ?? false;
38935
39188
  const g = svg.append("g").attr("class", "kanban-column").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
38936
39189
  const thisColBg = defaultColBg;
38937
- const thisColHeaderBg = col.color ? shapeFill(palette, col.color, isDark, { solid }) : defaultColHeaderBg;
39190
+ const thisColHeaderBg = col.color ? shapeFill(palette, col.color, isDark, { mode: fillMode }) : defaultColHeaderBg;
38938
39191
  const onHeaderText = col.color ? contrastText(
38939
39192
  thisColHeaderBg,
38940
39193
  palette.textOnFillLight,
38941
39194
  palette.textOnFillDark
38942
39195
  ) : palette.text;
38943
39196
  if (isColCollapsed) {
38944
- g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", sCollapsedColumnWidth).attr("height", colLayout.height).attr("rx", sColumnRadius).attr("fill", thisColBg);
39197
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", sCollapsedColumnWidth).attr("height", colLayout.height).attr("rx", sColumnRadius).attr("fill", fillMode === "outline" ? baseBg : thisColBg).call((sel) => {
39198
+ if (fillMode === "outline")
39199
+ sel.attr("stroke", wellStroke).attr("stroke-width", 1);
39200
+ });
38945
39201
  g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", sCollapsedColumnWidth).attr("height", sColumnHeaderHeight).attr("rx", sColumnHeaderRadius).attr("fill", thisColHeaderBg);
38946
39202
  g.append("text").attr("x", colLayout.x + sCollapsedColumnWidth / 2).attr("y", colLayout.y + sColumnHeaderHeight / 2 + sWipFontSize / 2 - 1).attr("font-size", sWipFontSize).attr("font-weight", "bold").attr("fill", col.color ? onHeaderText : palette.textMuted).attr("text-anchor", "middle").text(String(col.cards.length));
38947
39203
  g.append("text").attr("x", colLayout.x + sCollapsedColumnWidth / 2).attr("y", colLayout.y + sColumnHeaderHeight + sColumnPadding).attr("font-size", sCardTitleFontSize).attr("font-weight", "bold").attr("fill", palette.text).attr("text-anchor", "middle").attr("writing-mode", "tb").text(col.name);
38948
39204
  continue;
38949
39205
  }
38950
- g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", colLayout.height).attr("rx", sColumnRadius).attr("fill", thisColBg);
39206
+ g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", colLayout.height).attr("rx", sColumnRadius).attr("fill", fillMode === "outline" ? baseBg : thisColBg).call((sel) => {
39207
+ if (fillMode === "outline")
39208
+ sel.attr("stroke", wellStroke).attr("stroke-width", 1);
39209
+ });
38951
39210
  g.append("rect").attr("x", colLayout.x).attr("y", colLayout.y).attr("width", colLayout.width).attr("height", sColumnHeaderHeight).attr("rx", sColumnHeaderRadius).attr("fill", thisColHeaderBg);
38952
39211
  g.append("text").attr("x", colLayout.x + sColumnPadding).attr(
38953
39212
  "y",
@@ -38978,7 +39237,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
38978
39237
  palette,
38979
39238
  resolvedColor ?? palette.primary,
38980
39239
  isDark,
38981
- { solid }
39240
+ { mode: fillMode }
38982
39241
  );
38983
39242
  const cardStroke = resolvedColor ?? palette.textMuted;
38984
39243
  const onCardText = contrastText(
@@ -39005,7 +39264,7 @@ function renderKanban(container, parsed, palette, isDark, options) {
39005
39264
  renderInlineText(titleEl, card.title, palette, sCardTitleFontSize);
39006
39265
  if (hasMeta) {
39007
39266
  const separatorY = cy + sCardHeaderHeight;
39008
- cg.append("line").attr("x1", cx).attr("y1", separatorY).attr("x2", cx + cardLayout.width).attr("y2", separatorY).attr("stroke", solid ? onCardText : cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
39267
+ cg.append("line").attr("x1", cx).attr("y1", separatorY).attr("x2", cx + cardLayout.width).attr("y2", separatorY).attr("stroke", fillMode === "solid" ? onCardText : cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
39009
39268
  let metaY = separatorY + sCardSeparatorGap + sCardMetaFontSize;
39010
39269
  for (const meta of tagMeta) {
39011
39270
  cg.append("text").attr("x", cx + sCardPaddingX).attr("y", metaY).attr("font-size", sCardMetaFontSize).attr("fill", onCardText).text(`${meta.label}: `);
@@ -39224,7 +39483,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
39224
39483
  const isColCollapsed = collapsedColumns?.has(col.id) ?? false;
39225
39484
  const headerG = svg.append("g").attr("class", "kanban-column kanban-column-header").attr("data-column-id", col.id).attr("data-line-number", col.lineNumber);
39226
39485
  const colHeaderBg = col.color ? shapeFill(palette, col.color, isDark, {
39227
- solid: parsed.options["solid-fill"] === "on"
39486
+ mode: fillModeFromOptions(parsed.options)
39228
39487
  }) : defaultColHeaderBg;
39229
39488
  headerG.append("rect").attr("x", colInfo.x).attr("y", grid.startY).attr("width", colInfo.width).attr("height", sColumnHeaderHeight).attr("rx", sColumnHeaderRadius).attr("fill", colHeaderBg);
39230
39489
  if (isColCollapsed) {
@@ -39300,7 +39559,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
39300
39559
  palette,
39301
39560
  isDark,
39302
39561
  hiddenMetaGroups,
39303
- parsed.options["solid-fill"] === "on",
39562
+ fillModeFromOptions(parsed.options),
39304
39563
  sCardRadius,
39305
39564
  sCardPaddingX,
39306
39565
  sCardPaddingY,
@@ -39316,7 +39575,7 @@ function renderSwimlaneBoard(svg, parsed, baseLayout, swimlaneGroup, palette, is
39316
39575
  }
39317
39576
  }
39318
39577
  }
39319
- function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, solid, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
39578
+ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palette, isDark, hiddenMetaGroups, fillMode, sCardRadius = CARD_RADIUS, sCardPaddingX = CARD_PADDING_X, sCardPaddingY = CARD_PADDING_Y, sCardStrokeWidth = CARD_STROKE_WIDTH, sCardTitleFontSize = CARD_TITLE_FONT_SIZE, sCardMetaFontSize = CARD_META_FONT_SIZE, sCardHeaderHeight = CARD_HEADER_HEIGHT, sCardSeparatorGap = CARD_SEPARATOR_GAP, sCardMetaLineHeight = CARD_META_LINE_HEIGHT) {
39320
39579
  const card = cardLayout.card;
39321
39580
  const resolvedColor = resolveCardTagColor(card, tagGroups, activeTagGroup);
39322
39581
  const tagMeta = resolveCardTagMeta(card, tagGroups, hiddenMetaGroups);
@@ -39325,9 +39584,7 @@ function renderSwimlaneCard(parent, cardLayout, tagGroups, activeTagGroup, palet
39325
39584
  palette,
39326
39585
  resolvedColor ?? palette.primary,
39327
39586
  isDark,
39328
- {
39329
- ...solid !== void 0 && { solid }
39330
- }
39587
+ { mode: fillMode }
39331
39588
  );
39332
39589
  const cardStroke = resolvedColor ?? palette.textMuted;
39333
39590
  const onCardText = contrastText(
@@ -39371,6 +39628,7 @@ var init_renderer7 = __esm({
39371
39628
  "src/kanban/renderer.ts"() {
39372
39629
  "use strict";
39373
39630
  init_tag_groups();
39631
+ init_parsing();
39374
39632
  init_fonts();
39375
39633
  init_color_utils();
39376
39634
  init_inline_markdown();
@@ -39629,11 +39887,9 @@ function modifierColor(modifier, palette, colorOff) {
39629
39887
  return palette.colors.teal;
39630
39888
  }
39631
39889
  }
39632
- function nodeFill3(palette, isDark, modifier, nodeColor2, colorOff, solid) {
39890
+ function nodeFill3(palette, isDark, modifier, nodeColor2, colorOff, fillMode) {
39633
39891
  const color = nodeColor2 ?? modifierColor(modifier, palette, colorOff);
39634
- return shapeFill(palette, color, isDark, {
39635
- ...solid !== void 0 && { solid }
39636
- });
39892
+ return shapeFill(palette, color, isDark, { mode: fillMode });
39637
39893
  }
39638
39894
  function nodeStroke3(palette, modifier, nodeColor2, colorOff) {
39639
39895
  return nodeColor2 ?? modifierColor(modifier, palette, colorOff);
@@ -39811,14 +40067,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
39811
40067
  const colorOff = !!parsed.options?.["no-auto-color"];
39812
40068
  const neutralize = hasLegend && !isLegendExpanded && !node.color;
39813
40069
  const effectiveColor = neutralize ? palette.primary : node.color;
39814
- const solid = parsed.options?.["solid-fill"] === "on";
40070
+ const fillMode = fillModeFromOptions(parsed.options ?? {});
39815
40071
  const fill2 = nodeFill3(
39816
40072
  palette,
39817
40073
  isDark,
39818
40074
  node.modifier,
39819
40075
  effectiveColor,
39820
40076
  colorOff,
39821
- solid
40077
+ fillMode
39822
40078
  );
39823
40079
  const stroke2 = nodeStroke3(palette, node.modifier, effectiveColor, colorOff);
39824
40080
  const onFillText = contrastText(
@@ -39841,14 +40097,14 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
39841
40097
  const fields = node.members.filter((m) => !m.isMethod);
39842
40098
  const methods = node.members.filter((m) => m.isMethod);
39843
40099
  if (isEnum) {
39844
- nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
40100
+ nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
39845
40101
  let memberY = yPos + sCompartmentPaddingY;
39846
40102
  for (const member of node.members) {
39847
40103
  nodeG.append("text").attr("x", -w / 2 + sMemberPaddingX).attr("y", memberY + sMemberLineHeight / 2).attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", sMemberFontSize).text(member.name);
39848
40104
  memberY += sMemberLineHeight;
39849
40105
  }
39850
40106
  } else {
39851
- nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
40107
+ nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
39852
40108
  if (fields.length > 0) {
39853
40109
  let memberY = yPos + sCompartmentPaddingY;
39854
40110
  for (const field of fields) {
@@ -39864,7 +40120,7 @@ function renderClassDiagram(container, parsed, layout, palette, isDark, onClickI
39864
40120
  }
39865
40121
  }
39866
40122
  yPos += node.fieldsHeight;
39867
- nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
40123
+ nodeG.append("line").attr("x1", -w / 2).attr("y1", yPos).attr("x2", w / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.5);
39868
40124
  if (methods.length > 0) {
39869
40125
  let memberY = yPos + sCompartmentPaddingY;
39870
40126
  for (const method of methods) {
@@ -39958,6 +40214,7 @@ var DIAGRAM_PADDING4, MAX_SCALE3, CLASS_FONT_SIZE2, MEMBER_FONT_SIZE2, EDGE_LABE
39958
40214
  var init_renderer8 = __esm({
39959
40215
  "src/class/renderer.ts"() {
39960
40216
  "use strict";
40217
+ init_parsing();
39961
40218
  init_fonts();
39962
40219
  init_export_container();
39963
40220
  init_legend_constants();
@@ -40652,7 +40909,7 @@ function renderERDiagram(container, parsed, layout, palette, isDark, onClickItem
40652
40909
  const w = node.width;
40653
40910
  const h = node.height;
40654
40911
  const fill2 = shapeFill(palette, nodeColor2, isDark, {
40655
- solid: parsed.options["solid-fill"] === "on"
40912
+ mode: fillModeFromOptions(parsed.options)
40656
40913
  });
40657
40914
  const stroke2 = nodeColor2;
40658
40915
  const onFillText = contrastText(
@@ -40814,6 +41071,7 @@ var init_renderer9 = __esm({
40814
41071
  "src/er/renderer.ts"() {
40815
41072
  "use strict";
40816
41073
  init_tag_groups();
41074
+ init_parsing();
40817
41075
  init_fonts();
40818
41076
  init_color_utils();
40819
41077
  init_palettes();
@@ -41558,7 +41816,7 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
41558
41816
  hideDescriptions = false
41559
41817
  } = options;
41560
41818
  const hideDesc = hideDescriptions || parsed.options.noDescriptions;
41561
- const neutralFill = mix(palette.textMuted, palette.bg, 12);
41819
+ const neutralFill = parsed.options.fillMode === "outline" ? themeBaseBg(palette, isDark) : mix(palette.textMuted, palette.bg, 12);
41562
41820
  const tagGroups = [...parsed.tagGroups];
41563
41821
  const activeName = resolveActiveTagGroup(
41564
41822
  tagGroups,
@@ -41577,14 +41835,14 @@ function renderSketch(container, parsed, layout, palette, isDark, options = {})
41577
41835
  };
41578
41836
  }
41579
41837
  const fill2 = shapeFill(palette, tagColor, isDark, {
41580
- solid: parsed.options.solidFill
41838
+ mode: parsed.options.fillMode
41581
41839
  });
41582
41840
  return {
41583
41841
  fill: fill2,
41584
41842
  stroke: tagColor,
41585
41843
  // Label text takes the shape's own (tag) color — but for solid fills the
41586
41844
  // tag color would vanish into the fill, so keep a contrast color there.
41587
- text: parsed.options.solidFill ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : tagColor
41845
+ text: parsed.options.fillMode === "solid" ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : tagColor
41588
41846
  };
41589
41847
  };
41590
41848
  const showTitle = !!parsed.title;
@@ -41833,8 +42091,8 @@ function drawNode(layer, node, colors, palette, isDark, tagGroups) {
41833
42091
  const rows = node.isCollapsedBox ? [] : metaRows(node.metadata, tagGroups);
41834
42092
  const badge = node.shape !== "rectangle";
41835
42093
  const labelInset = badge ? 22 : 0;
41836
- const solid = colors.stroke === colors.fill;
41837
- const ruleColor = solid ? colors.text : colors.stroke;
42094
+ const solidLike = colors.stroke === colors.fill;
42095
+ const ruleColor = solidLike ? colors.text : colors.stroke;
41838
42096
  if (node.description && !node.isCollapsedBox) {
41839
42097
  const fitH = fitWrapped(
41840
42098
  node.label,
@@ -41903,7 +42161,7 @@ function drawNode(layer, node, colors, palette, isDark, tagGroups) {
41903
42161
  lineHeight: CARD_META_FONT + 5,
41904
42162
  separatorGap: 8,
41905
42163
  separatorColor: ruleColor,
41906
- textColor: solid ? colors.text : palette.text,
42164
+ textColor: solidLike ? colors.text : palette.text,
41907
42165
  keyX: 12
41908
42166
  }
41909
42167
  } : {}
@@ -42412,7 +42670,7 @@ function fitLabelToHeader(label, nodeWidth, maxLines) {
42412
42670
  const truncated = truncateText(label, MIN_NODE_FONT_SIZE, maxTextWidth);
42413
42671
  return { lines: [truncated], fontSize: MIN_NODE_FONT_SIZE };
42414
42672
  }
42415
- function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, solid) {
42673
+ function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, fillMode) {
42416
42674
  const neutralFill = mix(palette.bg, palette.text, isDark ? 90 : 95);
42417
42675
  if (value.active) {
42418
42676
  if (node.value === void 0) {
@@ -42424,9 +42682,7 @@ function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, so
42424
42682
  return { fill: neutralFill, stroke: value.hue, text: text3 };
42425
42683
  }
42426
42684
  const rampColor2 = value.fillForValue(node.value);
42427
- const fill3 = shapeFill(palette, rampColor2, isDark, {
42428
- ...solid !== void 0 && { solid }
42429
- });
42685
+ const fill3 = shapeFill(palette, rampColor2, isDark, { mode: fillMode });
42430
42686
  const stroke3 = value.twoColor ? rampColor2 : value.hue;
42431
42687
  const text2 = contrastText(
42432
42688
  fill3,
@@ -42441,9 +42697,7 @@ function nodeColors(node, tagGroups, activeGroupName, palette, isDark, value, so
42441
42697
  activeGroupName
42442
42698
  );
42443
42699
  if (tagColor) {
42444
- const fill3 = shapeFill(palette, tagColor, isDark, {
42445
- ...solid !== void 0 && { solid }
42446
- });
42700
+ const fill3 = shapeFill(palette, tagColor, isDark, { mode: fillMode });
42447
42701
  const stroke3 = tagColor;
42448
42702
  const text2 = contrastText(
42449
42703
  fill3,
@@ -42755,7 +43009,7 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
42755
43009
  }
42756
43010
  if (isHidden) continue;
42757
43011
  }
42758
- const solid = parsed.options["solid-fill"] === "on";
43012
+ const fillMode = fillModeFromOptions(parsed.options);
42759
43013
  const colors = nodeColors(
42760
43014
  node,
42761
43015
  parsed.tagGroups,
@@ -42768,9 +43022,9 @@ function renderBoxesAndLines(container, parsed, layout, palette, isDark, options
42768
43022
  twoColor: rampLow !== void 0,
42769
43023
  fillForValue
42770
43024
  },
42771
- solid
43025
+ fillMode
42772
43026
  );
42773
- const dividerStroke = solid ? colors.text : colors.stroke;
43027
+ const dividerStroke = fillMode === "solid" ? colors.text : colors.stroke;
42774
43028
  const nodeG = diagramG.append("g").attr("class", "bl-node").attr("transform", `translate(${ln.x},${ln.y})`).attr("data-line-number", node.lineNumber).attr("data-node-id", node.label).style("cursor", onClickItem ? "pointer" : "default").style("--bl-node-stroke", colors.stroke);
42775
43029
  for (const [key, val] of Object.entries(node.metadata)) {
42776
43030
  nodeG.attr(`data-tag-${key.toLowerCase()}`, val.toLowerCase());
@@ -43032,6 +43286,7 @@ var DIAGRAM_PADDING7, NODE_FONT_SIZE, MIN_NODE_FONT_SIZE, EDGE_LABEL_FONT_SIZE6,
43032
43286
  var init_renderer11 = __esm({
43033
43287
  "src/boxes-and-lines/renderer.ts"() {
43034
43288
  "use strict";
43289
+ init_parsing();
43035
43290
  init_note_box();
43036
43291
  init_fonts();
43037
43292
  init_legend_integration();
@@ -46252,7 +46507,7 @@ function renderSwimlaneForExport(container, parsed, layout, palette, isDark, opt
46252
46507
  laneColorById.set(lane.id, hex);
46253
46508
  });
46254
46509
  const isLR = parsed.direction === "LR";
46255
- const solid = parsed.options["solid-fill"] === "on";
46510
+ const fillMode = fillModeFromOptions(parsed.options);
46256
46511
  const laneFill = (hex) => mix(hex, baseBg, 9);
46257
46512
  const haloAt = (cross) => {
46258
46513
  for (const band of layout.lanes) {
@@ -46301,28 +46556,35 @@ function renderSwimlaneForExport(container, parsed, layout, palette, isDark, opt
46301
46556
  phaseG.append("text").attr("x", isLR ? band.x + band.width / 2 : band.headerSize / 2).attr("y", isLR ? band.headerSize / 2 : band.y + band.height / 2).attr("text-anchor", "middle").attr("dominant-baseline", "middle").attr("font-size", PHASE_LABEL_FONT).attr("font-weight", "700").attr("letter-spacing", "0.06em").attr("fill", palette.textMuted).attr("data-line-number", String(band.lineNumber)).text(band.label);
46302
46557
  });
46303
46558
  const activeTag = opts.activeTagGroup ?? null;
46559
+ const outline = fillMode === "outline";
46304
46560
  const nodeFill7 = (n) => {
46305
46561
  if (activeTag) {
46306
46562
  const key = tagAttrKey(activeTag);
46307
46563
  if (n.tags[key]) {
46308
46564
  const c = resolveTagColor(n.tags, [...parsed.tagGroups], activeTag);
46309
46565
  if (c && c !== "#999999")
46310
- return { fill: solid ? c : mix(c, baseBg, 22), stroke: c };
46566
+ return {
46567
+ fill: fillMode === "solid" ? c : outline ? baseBg : mix(c, baseBg, 22),
46568
+ stroke: c
46569
+ };
46311
46570
  }
46312
46571
  }
46313
46572
  if (n.shape === "terminal") {
46314
46573
  if (n.event === "error")
46315
46574
  return {
46316
- fill: solid ? ev.error : mix(ev.error, baseBg, 22),
46575
+ fill: fillMode === "solid" ? ev.error : outline ? baseBg : mix(ev.error, baseBg, 22),
46317
46576
  stroke: ev.error
46318
46577
  };
46319
46578
  if (n.event === "success")
46320
46579
  return {
46321
- fill: solid ? ev.success : mix(ev.success, baseBg, 22),
46580
+ fill: fillMode === "solid" ? ev.success : outline ? baseBg : mix(ev.success, baseBg, 22),
46322
46581
  stroke: ev.success
46323
46582
  };
46324
46583
  if (n.event === "terminate")
46325
- return { fill: mix(palette.text, baseBg, 30), stroke: palette.text };
46584
+ return {
46585
+ fill: outline ? baseBg : mix(palette.text, baseBg, 30),
46586
+ stroke: palette.text
46587
+ };
46326
46588
  return { fill: palette.bg, stroke: palette.textMuted };
46327
46589
  }
46328
46590
  if (n.shape === "exclusive" || n.shape === "parallel") {
@@ -46333,8 +46595,8 @@ function renderSwimlaneForExport(container, parsed, layout, palette, isDark, opt
46333
46595
  }
46334
46596
  const hex = laneColorById.get(n.lane) ?? palette.border;
46335
46597
  return {
46336
- fill: solid ? hex : mix(hex, baseBg, 20),
46337
- stroke: mix(hex, palette.text, 40)
46598
+ fill: fillMode === "solid" ? hex : outline ? baseBg : mix(hex, baseBg, 20),
46599
+ stroke: outline ? hex : mix(hex, palette.text, 40)
46338
46600
  };
46339
46601
  };
46340
46602
  const nodeById = new Map(layout.nodes.map((n) => [n.id, n]));
@@ -46519,6 +46781,7 @@ var NODE_FONT_SIZE2, LANE_LABEL_FONT, PHASE_LABEL_FONT, EDGE_LABEL_FONT, NODE_RX
46519
46781
  var init_renderer12 = __esm({
46520
46782
  "src/swimlane/renderer.ts"() {
46521
46783
  "use strict";
46784
+ init_parsing();
46522
46785
  init_fonts();
46523
46786
  init_arrow_markers();
46524
46787
  init_title_constants();
@@ -47092,7 +47355,7 @@ function baseColor(node, parsed, palette, activeTagGroup) {
47092
47355
  function renderFamilyForExport(container, parsed, layout, palette, isDark, opts = {}) {
47093
47356
  d3Selection16.select(container).selectAll(":not([data-d3-tooltip])").remove();
47094
47357
  const activeTagGroup = opts.activeTagGroup ?? null;
47095
- const solid = parsed.options["solid-fill"] === "on";
47358
+ const fillMode = fillModeFromOptions(parsed.options);
47096
47359
  const noDaggers = parsed.options["no-daggers"] === "true";
47097
47360
  const baseBg = themeBaseBg(palette, isDark);
47098
47361
  const PAD3 = 20;
@@ -47206,7 +47469,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
47206
47469
  for (const node of layout.nodes) {
47207
47470
  const isPh = !!node.placeholder;
47208
47471
  const base = baseColor(node, parsed, palette, activeTagGroup);
47209
- const fill2 = isPh ? mix(palette.textMuted, baseBg, 6) : shapeFill(palette, base, isDark, { solid });
47472
+ const fill2 = isPh ? mix(palette.textMuted, baseBg, 6) : shapeFill(palette, base, isDark, { mode: fillMode });
47210
47473
  const stroke2 = isPh ? palette.textMuted : base;
47211
47474
  const labelColor = isPh ? palette.textMuted : contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark);
47212
47475
  const g = cardsG.append("g").attr("class", "family-card").attr("transform", `translate(${node.x}, ${node.y})`).attr("data-line-number", String(node.lineNumber)).attr("data-person-id", node.id);
@@ -47227,7 +47490,7 @@ function renderFamilyForExport(container, parsed, layout, palette, isDark, opts
47227
47490
  focusG.append("circle").attr("cx", fx).attr("cy", fy).attr("r", 1.6).attr("fill", labelColor);
47228
47491
  const rows = familyCardRows(node);
47229
47492
  if (rows.length === 0) continue;
47230
- g.append("line").attr("x1", 0).attr("y1", HEADER_HEIGHT).attr("x2", node.width).attr("y2", HEADER_HEIGHT).attr("stroke", solid ? labelColor : stroke2).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
47493
+ g.append("line").attr("x1", 0).attr("y1", HEADER_HEIGHT).attr("x2", node.width).attr("y2", HEADER_HEIGHT).attr("stroke", fillMode === "solid" ? labelColor : stroke2).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
47231
47494
  const maxKeyWidth = Math.max(
47232
47495
  0,
47233
47496
  ...rows.filter((r) => !r.year).map((r) => measureText(`${r.key}: `, META_FONT_SIZE))
@@ -47273,6 +47536,7 @@ var KEY_X2, KEY_VALUE_GAP2, BAR_DOT_R, TITLE_RESERVE, DIM_OPACITY, ROMAN;
47273
47536
  var init_renderer13 = __esm({
47274
47537
  "src/family/renderer.ts"() {
47275
47538
  "use strict";
47539
+ init_parsing();
47276
47540
  init_fonts();
47277
47541
  init_title_constants();
47278
47542
  init_color_utils();
@@ -47900,11 +48164,9 @@ __export(renderer_exports13, {
47900
48164
  renderMindmapForExport: () => renderMindmapForExport
47901
48165
  });
47902
48166
  import * as d3Selection17 from "d3-selection";
47903
- function nodeFill4(palette, isDark, nodeColor2, solid) {
48167
+ function nodeFill4(palette, isDark, nodeColor2, fillMode) {
47904
48168
  const color = nodeColor2 ?? palette.primary;
47905
- return shapeFill(palette, color, isDark, {
47906
- ...solid !== void 0 && { solid }
47907
- });
48169
+ return shapeFill(palette, color, isDark, { mode: fillMode });
47908
48170
  }
47909
48171
  function nodeStroke4(palette, nodeColor2) {
47910
48172
  return nodeColor2 ?? palette.primary;
@@ -48092,7 +48354,7 @@ function renderMindmap(container, parsed, layout, palette, isDark, onClickItem,
48092
48354
  palette,
48093
48355
  isDark,
48094
48356
  effectiveColor,
48095
- parsed.options["solid-fill"] === "on"
48357
+ fillModeFromOptions(parsed.options)
48096
48358
  );
48097
48359
  const stroke2 = nodeStroke4(palette, effectiveColor);
48098
48360
  const onFillText = contrastText(
@@ -48222,6 +48484,7 @@ var init_renderer14 = __esm({
48222
48484
  "src/mindmap/renderer.ts"() {
48223
48485
  "use strict";
48224
48486
  init_tag_groups();
48487
+ init_parsing();
48225
48488
  init_fonts();
48226
48489
  init_export_container();
48227
48490
  init_color_utils();
@@ -48601,7 +48864,7 @@ function renderWireframe(container, parsed, layout, palette, isDark, _onClickIte
48601
48864
  isTransparent: effectiveTheme === "transparent",
48602
48865
  isDark,
48603
48866
  showGroupLabels: opts.showGroupLabels ?? true,
48604
- solid: parsed.options["solid-fill"] === "on"
48867
+ fillMode: fillModeFromOptions(parsed.options)
48605
48868
  };
48606
48869
  if (!ctx.isTransparent) {
48607
48870
  svg.append("rect").attr("width", layout.width).attr("height", layout.height).attr("fill", palette.bg).attr("rx", 8);
@@ -48985,7 +49248,7 @@ function renderAlert(g, node, ctx) {
48985
49248
  const { palette, isDark, isTransparent } = ctx;
48986
49249
  const el = node.element;
48987
49250
  const color = getElementSemanticColor(el, palette) || palette.accent;
48988
- const fill2 = isTransparent ? null : shapeFill(palette, color, isDark, { solid: ctx.solid });
49251
+ const fill2 = isTransparent ? null : shapeFill(palette, color, isDark, { mode: ctx.fillMode });
48989
49252
  if (fill2) {
48990
49253
  g.append("rect").attr("width", node.width).attr("height", node.height).attr("fill", fill2).attr("rx", 4);
48991
49254
  }
@@ -49093,6 +49356,7 @@ var INPUT_CORNER, BUTTON_CORNER, GROUP_CORNER, SEMANTIC_COLORS;
49093
49356
  var init_renderer15 = __esm({
49094
49357
  "src/wireframe/renderer.ts"() {
49095
49358
  "use strict";
49359
+ init_parsing();
49096
49360
  init_fonts();
49097
49361
  init_color_utils();
49098
49362
  init_title_constants();
@@ -50811,11 +51075,9 @@ function typeColor(type, palette, nodeColor2) {
50811
51075
  return palette.colors.teal;
50812
51076
  }
50813
51077
  }
50814
- function nodeFill5(palette, isDark, type, nodeColor2, solid) {
51078
+ function nodeFill5(palette, isDark, type, nodeColor2, fillMode) {
50815
51079
  const color = typeColor(type, palette, nodeColor2);
50816
- return shapeFill(palette, color, isDark, {
50817
- ...solid !== void 0 && { solid }
50818
- });
51080
+ return shapeFill(palette, color, isDark, { mode: fillMode });
50819
51081
  }
50820
51082
  function nodeStroke5(palette, type, nodeColor2) {
50821
51083
  return typeColor(type, palette, nodeColor2);
@@ -50952,8 +51214,8 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
50952
51214
  }
50953
51215
  const w = node.width;
50954
51216
  const h = node.height;
50955
- const solid = parsed.options["solid-fill"] === "on";
50956
- const fill2 = nodeFill5(palette, isDark, node.type, node.color, solid);
51217
+ const fillMode = fillModeFromOptions(parsed.options);
51218
+ const fill2 = nodeFill5(palette, isDark, node.type, node.color, fillMode);
50957
51219
  const stroke2 = nodeStroke5(palette, node.type, node.color);
50958
51220
  const onFillText = contrastText(
50959
51221
  fill2,
@@ -50982,7 +51244,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
50982
51244
  nodeG.append("text").attr("x", 0).attr("y", yPos + NAME_FONT_SIZE2 / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("fill", onFillText).attr("font-size", NAME_FONT_SIZE2).attr("font-weight", "bold").text(node.name);
50983
51245
  }
50984
51246
  yPos += NAME_HEIGHT2;
50985
- nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
51247
+ nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
50986
51248
  yPos += DIVIDER_GAP2;
50987
51249
  if (node.description) {
50988
51250
  const contentWidth = w - CARD_H_PAD5 * 2;
@@ -51005,7 +51267,7 @@ function renderC4Context(container, parsed, layout, palette, isDark, onClickItem
51005
51267
  if (node.drillable) {
51006
51268
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
51007
51269
  nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
51008
- nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
51270
+ nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", fillMode === "solid" ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
51009
51271
  }
51010
51272
  }
51011
51273
  if (hasLegend) {
@@ -51514,8 +51776,8 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
51514
51776
  }
51515
51777
  const w = node.width;
51516
51778
  const h = node.height;
51517
- const solid = parsed.options["solid-fill"] === "on";
51518
- const fill2 = nodeFill5(palette, isDark, node.type, node.color, solid);
51779
+ const fillMode = fillModeFromOptions(parsed.options);
51780
+ const fill2 = nodeFill5(palette, isDark, node.type, node.color, fillMode);
51519
51781
  const stroke2 = nodeStroke5(palette, node.type, node.color);
51520
51782
  const onFillText = contrastText(
51521
51783
  fill2,
@@ -51583,7 +51845,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
51583
51845
  }
51584
51846
  const metaEntries = collectCardMetadata(node.metadata);
51585
51847
  if (metaEntries.length > 0) {
51586
- nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
51848
+ nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
51587
51849
  yPos += DIVIDER_GAP2;
51588
51850
  const maxKeyWidth = Math.max(
51589
51851
  ...metaEntries.map((e) => measureText(`${e.key}: `, META_FONT_SIZE))
@@ -51596,7 +51858,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
51596
51858
  }
51597
51859
  }
51598
51860
  } else {
51599
- nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", solid ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
51861
+ nodeG.append("line").attr("x1", -w / 2 + CARD_H_PAD5 / 2).attr("y1", yPos).attr("x2", w / 2 - CARD_H_PAD5 / 2).attr("y2", yPos).attr("stroke", fillMode === "solid" ? onFillText : stroke2).attr("stroke-width", 0.5).attr("stroke-opacity", 0.4);
51600
51862
  yPos += DIVIDER_GAP2;
51601
51863
  if (node.description) {
51602
51864
  const contentWidth = w - CARD_H_PAD5 * 2;
@@ -51620,7 +51882,7 @@ function renderC4Containers(container, parsed, layout, palette, isDark, onClickI
51620
51882
  if (node.drillable) {
51621
51883
  const clipId = `clip-drill-${node.id.replace(/\s+/g, "-")}`;
51622
51884
  nodeG.append("clipPath").attr("id", clipId).append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", CARD_RADIUS);
51623
- nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", solid ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
51885
+ nodeG.append("rect").attr("x", -w / 2).attr("y", h / 2 - DRILL_BAR_HEIGHT).attr("width", w).attr("height", DRILL_BAR_HEIGHT).attr("fill", fillMode === "solid" ? onFillText : stroke2).attr("clip-path", `url(#${clipId})`).attr("class", "c4-drill-bar");
51624
51886
  }
51625
51887
  }
51626
51888
  if (hasLegend) {
@@ -51753,6 +52015,7 @@ var init_renderer16 = __esm({
51753
52015
  "src/c4/renderer.ts"() {
51754
52016
  "use strict";
51755
52017
  init_tag_groups();
52018
+ init_parsing();
51756
52019
  init_fonts();
51757
52020
  init_color_utils();
51758
52021
  init_inline_markdown();
@@ -52170,28 +52433,34 @@ function shapeDefaultColor(shape, palette, isEndTerminal, colorOff) {
52170
52433
  return palette.colors.blue;
52171
52434
  }
52172
52435
  }
52173
- function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff, solid) {
52436
+ function nodeFill6(palette, isDark, shape, nodeColor2, isEndTerminal, colorOff, fillMode) {
52174
52437
  const color = nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
52175
- return shapeFill(palette, color, isDark, {
52176
- ...solid !== void 0 && { solid }
52177
- });
52438
+ return shapeFill(palette, color, isDark, { mode: fillMode });
52178
52439
  }
52179
52440
  function nodeStroke6(palette, shape, nodeColor2, isEndTerminal, colorOff) {
52180
52441
  return nodeColor2 ?? shapeDefaultColor(shape, palette, isEndTerminal, colorOff);
52181
52442
  }
52182
- function renderTerminal(g, node, palette, isDark, isEnd, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52443
+ function renderTerminal(g, node, palette, isDark, isEnd, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52183
52444
  const w = node.width;
52184
52445
  const h = node.height;
52185
52446
  const rx = h / 2;
52186
52447
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", rx).attr("ry", rx).attr(
52187
52448
  "fill",
52188
- nodeFill6(palette, isDark, node.shape, node.color, isEnd, colorOff, solid)
52449
+ nodeFill6(
52450
+ palette,
52451
+ isDark,
52452
+ node.shape,
52453
+ node.color,
52454
+ isEnd,
52455
+ colorOff,
52456
+ fillMode
52457
+ )
52189
52458
  ).attr(
52190
52459
  "stroke",
52191
52460
  nodeStroke6(palette, node.shape, node.color, isEnd, colorOff)
52192
52461
  ).attr("stroke-width", sNodeStrokeWidth);
52193
52462
  }
52194
- function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52463
+ function renderProcess(g, node, palette, isDark, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52195
52464
  const w = node.width;
52196
52465
  const h = node.height;
52197
52466
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr(
@@ -52203,14 +52472,14 @@ function renderProcess(g, node, palette, isDark, colorOff, solid, sNodeStrokeWid
52203
52472
  node.color,
52204
52473
  void 0,
52205
52474
  colorOff,
52206
- solid
52475
+ fillMode
52207
52476
  )
52208
52477
  ).attr(
52209
52478
  "stroke",
52210
52479
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
52211
52480
  ).attr("stroke-width", sNodeStrokeWidth);
52212
52481
  }
52213
- function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52482
+ function renderDecision(g, node, palette, isDark, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH) {
52214
52483
  const w = node.width / 2;
52215
52484
  const h = node.height / 2;
52216
52485
  const points = [`${0},${-h}`, `${w},${0}`, `${0},${h}`, `${-w},${0}`].join(
@@ -52225,14 +52494,14 @@ function renderDecision(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
52225
52494
  node.color,
52226
52495
  void 0,
52227
52496
  colorOff,
52228
- solid
52497
+ fillMode
52229
52498
  )
52230
52499
  ).attr(
52231
52500
  "stroke",
52232
52501
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
52233
52502
  ).attr("stroke-width", sNodeStrokeWidth);
52234
52503
  }
52235
- function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
52504
+ function renderIO(g, node, palette, isDark, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW) {
52236
52505
  const w = node.width / 2;
52237
52506
  const h = node.height / 2;
52238
52507
  const sk = sIoSkew;
@@ -52251,14 +52520,14 @@ function renderIO(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth =
52251
52520
  node.color,
52252
52521
  void 0,
52253
52522
  colorOff,
52254
- solid
52523
+ fillMode
52255
52524
  )
52256
52525
  ).attr(
52257
52526
  "stroke",
52258
52527
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
52259
52528
  ).attr("stroke-width", sNodeStrokeWidth);
52260
52529
  }
52261
- function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
52530
+ function renderSubroutine(g, node, palette, isDark, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH, sSubroutineInset = SUBROUTINE_INSET) {
52262
52531
  const w = node.width;
52263
52532
  const h = node.height;
52264
52533
  const s = nodeStroke6(palette, node.shape, node.color, void 0, colorOff);
@@ -52269,14 +52538,14 @@ function renderSubroutine(g, node, palette, isDark, colorOff, solid, sNodeStroke
52269
52538
  node.color,
52270
52539
  void 0,
52271
52540
  colorOff,
52272
- solid
52541
+ fillMode
52273
52542
  );
52274
- const innerStroke = solid ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : s;
52543
+ const innerStroke = fillMode === "solid" ? contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark) : s;
52275
52544
  g.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", 3).attr("ry", 3).attr("fill", fill2).attr("stroke", s).attr("stroke-width", sNodeStrokeWidth);
52276
52545
  g.append("line").attr("x1", -w / 2 + sSubroutineInset).attr("y1", -h / 2).attr("x2", -w / 2 + sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
52277
52546
  g.append("line").attr("x1", w / 2 - sSubroutineInset).attr("y1", -h / 2).attr("x2", w / 2 - sSubroutineInset).attr("y2", h / 2).attr("stroke", innerStroke).attr("stroke-width", sNodeStrokeWidth);
52278
52547
  }
52279
- function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
52548
+ function renderDocument(g, node, palette, isDark, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH, sDocWaveHeight = DOC_WAVE_HEIGHT) {
52280
52549
  const w = node.width;
52281
52550
  const h = node.height;
52282
52551
  const waveH = sDocWaveHeight;
@@ -52300,14 +52569,14 @@ function renderDocument(g, node, palette, isDark, colorOff, solid, sNodeStrokeWi
52300
52569
  node.color,
52301
52570
  void 0,
52302
52571
  colorOff,
52303
- solid
52572
+ fillMode
52304
52573
  )
52305
52574
  ).attr(
52306
52575
  "stroke",
52307
52576
  nodeStroke6(palette, node.shape, node.color, void 0, colorOff)
52308
52577
  ).attr("stroke-width", sNodeStrokeWidth);
52309
52578
  }
52310
- function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, solid, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
52579
+ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, fillMode, sNodeStrokeWidth = NODE_STROKE_WIDTH, sIoSkew = IO_SKEW, sSubroutineInset = SUBROUTINE_INSET, sDocWaveHeight = DOC_WAVE_HEIGHT) {
52311
52580
  switch (node.shape) {
52312
52581
  case "terminal":
52313
52582
  renderTerminal(
@@ -52317,7 +52586,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52317
52586
  isDark,
52318
52587
  endTerminalIds.has(node.id),
52319
52588
  colorOff,
52320
- solid,
52589
+ fillMode,
52321
52590
  sNodeStrokeWidth
52322
52591
  );
52323
52592
  break;
@@ -52328,7 +52597,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52328
52597
  palette,
52329
52598
  isDark,
52330
52599
  colorOff,
52331
- solid,
52600
+ fillMode,
52332
52601
  sNodeStrokeWidth
52333
52602
  );
52334
52603
  break;
@@ -52339,7 +52608,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52339
52608
  palette,
52340
52609
  isDark,
52341
52610
  colorOff,
52342
- solid,
52611
+ fillMode,
52343
52612
  sNodeStrokeWidth
52344
52613
  );
52345
52614
  break;
@@ -52350,7 +52619,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52350
52619
  palette,
52351
52620
  isDark,
52352
52621
  colorOff,
52353
- solid,
52622
+ fillMode,
52354
52623
  sNodeStrokeWidth,
52355
52624
  sIoSkew
52356
52625
  );
@@ -52362,7 +52631,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52362
52631
  palette,
52363
52632
  isDark,
52364
52633
  colorOff,
52365
- solid,
52634
+ fillMode,
52366
52635
  sNodeStrokeWidth,
52367
52636
  sSubroutineInset
52368
52637
  );
@@ -52374,7 +52643,7 @@ function renderNodeShape(g, node, palette, isDark, endTerminalIds, colorOff, sol
52374
52643
  palette,
52375
52644
  isDark,
52376
52645
  colorOff,
52377
- solid,
52646
+ fillMode,
52378
52647
  sNodeStrokeWidth,
52379
52648
  sDocWaveHeight
52380
52649
  );
@@ -52507,7 +52776,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
52507
52776
  }
52508
52777
  }
52509
52778
  const colorOff = graph.options?.["color"] === "off";
52510
- const solid = graph.options?.["solid-fill"] === "on";
52779
+ const fillMode = fillModeFromOptions(graph.options ?? {});
52511
52780
  const noNotes = graph.options?.["no-notes"] === "on";
52512
52781
  for (const node of layout.nodes) {
52513
52782
  const nodeG = contentG.append("g").attr("transform", `translate(${node.x}, ${node.y})`).attr("class", "fc-node").attr("data-line-number", String(node.lineNumber)).attr("data-node-id", node.id);
@@ -52524,7 +52793,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
52524
52793
  isDark,
52525
52794
  endTerminalIds,
52526
52795
  colorOff,
52527
- solid,
52796
+ fillMode,
52528
52797
  sNodeStrokeWidth,
52529
52798
  sIoSkew,
52530
52799
  sSubroutineInset,
@@ -52538,7 +52807,7 @@ function renderFlowchart(container, graph, layout, palette, isDark, onClickItem,
52538
52807
  node.color,
52539
52808
  isEnd,
52540
52809
  colorOff,
52541
- solid
52810
+ fillMode
52542
52811
  );
52543
52812
  nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr(
52544
52813
  "fill",
@@ -52625,6 +52894,7 @@ var DIAGRAM_PADDING10, MAX_SCALE6, NODE_FONT_SIZE3, EDGE_LABEL_FONT_SIZE9, ARROW
52625
52894
  var init_flowchart_renderer = __esm({
52626
52895
  "src/graph/flowchart-renderer.ts"() {
52627
52896
  "use strict";
52897
+ init_parsing();
52628
52898
  init_arrow_markers();
52629
52899
  init_fit_canvas();
52630
52900
  init_fonts();
@@ -54847,10 +55117,10 @@ function worstNodeSeverity(node, slo) {
54847
55117
  }
54848
55118
  return worst;
54849
55119
  }
54850
- function nodeColor(_node, palette, isDark, severity, solid) {
55120
+ function nodeColor(_node, palette, isDark, severity, fillMode) {
54851
55121
  if (severity === "overloaded") {
54852
55122
  const fill2 = shapeFill(palette, COLOR_OVERLOADED, isDark, {
54853
- ...solid !== void 0 && { solid }
55123
+ mode: fillMode
54854
55124
  });
54855
55125
  return {
54856
55126
  fill: fill2,
@@ -54863,9 +55133,7 @@ function nodeColor(_node, palette, isDark, severity, solid) {
54863
55133
  };
54864
55134
  }
54865
55135
  if (severity === "warning") {
54866
- const fill2 = shapeFill(palette, COLOR_WARNING, isDark, {
54867
- ...solid !== void 0 && { solid }
54868
- });
55136
+ const fill2 = shapeFill(palette, COLOR_WARNING, isDark, { mode: fillMode });
54869
55137
  return {
54870
55138
  fill: fill2,
54871
55139
  stroke: COLOR_WARNING,
@@ -54877,9 +55145,7 @@ function nodeColor(_node, palette, isDark, severity, solid) {
54877
55145
  };
54878
55146
  }
54879
55147
  if (severity === "healthy") {
54880
- const fill2 = shapeFill(palette, COLOR_HEALTHY, isDark, {
54881
- ...solid !== void 0 && { solid }
54882
- });
55148
+ const fill2 = shapeFill(palette, COLOR_HEALTHY, isDark, { mode: fillMode });
54883
55149
  return {
54884
55150
  fill: fill2,
54885
55151
  stroke: COLOR_HEALTHY,
@@ -55004,7 +55270,7 @@ function renderNodes(svg, nodes, palette, isDark, animate, expandedNodeIds, acti
55004
55270
  for (const node of nodes) {
55005
55271
  const slo = !node.isEdge && diagramOptions ? resolveNodeSlo(node, diagramOptions) : null;
55006
55272
  const severity = worstNodeSeverity(node, slo);
55007
- const nodeColors2 = nodeColor(node, palette, isDark, severity, false);
55273
+ const nodeColors2 = nodeColor(node, palette, isDark, severity, void 0);
55008
55274
  const textFill = nodeColors2.textFill;
55009
55275
  let { fill: fill2, stroke: stroke2 } = nodeColors2;
55010
55276
  if (activeGroup && tagGroups && !node.isEdge) {
@@ -57757,7 +58023,10 @@ function paintAnalysisRowMode(svg, resolved, palette, isDark, state, captionBull
57757
58023
  isDark
57758
58024
  };
57759
58025
  if (w.kind === "tornado") {
57760
- renderTornadoBlock(svg, state.tornadoRows, args);
58026
+ renderTornadoBlock(svg, state.tornadoRows, {
58027
+ ...args,
58028
+ fillMode: resolved.options.fillMode
58029
+ });
57761
58030
  } else {
57762
58031
  const scurveTitle = !state.summaryRendered && captionBullets.length > 0 ? (
57763
58032
  // In-bounds by length check.
@@ -57875,7 +58144,10 @@ function paintAnalysisStackMode(svg, resolved, palette, isDark, state, captionBu
57875
58144
  };
57876
58145
  switch (item.kind) {
57877
58146
  case "tornado":
57878
- renderTornadoBlock(svg, state.tornadoRows, args);
58147
+ renderTornadoBlock(svg, state.tornadoRows, {
58148
+ ...args,
58149
+ fillMode: resolved.options.fillMode
58150
+ });
57879
58151
  break;
57880
58152
  case "scurve": {
57881
58153
  const scurveTitle = !state.summaryRendered && captionBullets.length > 0 ? (
@@ -57981,7 +58253,7 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
57981
58253
  if (layout.groups.length === 0) return;
57982
58254
  const layer = root.append("g").attr("class", "pert-groups");
57983
58255
  const unit = resolved.options.timeUnit;
57984
- const solid = resolved.options.solidFill === true;
58256
+ const fillMode = resolved.options.fillMode;
57985
58257
  const containerFill3 = mix(palette.surface, palette.bg, 40);
57986
58258
  const containerStroke3 = palette.textMuted;
57987
58259
  const mcOn = resolved.monteCarloResult !== null;
@@ -58034,7 +58306,9 @@ function renderGroups2(root, resolved, layout, palette, isDark, collapsedSet, si
58034
58306
  "?"
58035
58307
  );
58036
58308
  const cardBaseColor = bandColor(memberBand, palette, palette.primary);
58037
- const cardFill = shapeFill(palette, cardBaseColor, isDark, { solid });
58309
+ const cardFill = shapeFill(palette, cardBaseColor, isDark, {
58310
+ mode: fillMode
58311
+ });
58038
58312
  const cardLabelColor = contrastText(
58039
58313
  cardFill,
58040
58314
  palette.textOnFillLight,
@@ -58162,7 +58436,7 @@ function renderNodes2(root, _defs, resolved, layout, palette, isDark, sizing, on
58162
58436
  const unit = resolved.options.timeUnit;
58163
58437
  const sprintMode = resolved.options.sprintMode;
58164
58438
  const sprintNumber = resolved.options.sprintNumber ?? 1;
58165
- const solid = resolved.options.solidFill === true;
58439
+ const fillMode = resolved.options.fillMode;
58166
58440
  const activeTagGroup = resolveActiveTagGroup(
58167
58441
  resolved.tagGroups,
58168
58442
  resolved.options.activeTag,
@@ -58217,7 +58491,7 @@ function renderNodes2(root, _defs, resolved, layout, palette, isDark, sizing, on
58217
58491
  );
58218
58492
  }
58219
58493
  const baseColor2 = bandColor(band, palette, palette.primary);
58220
- const fill2 = shapeFill(palette, baseColor2, isDark, { solid });
58494
+ const fill2 = shapeFill(palette, baseColor2, isDark, { mode: fillMode });
58221
58495
  const labelColor = contrastText(
58222
58496
  fill2,
58223
58497
  palette.textOnFillLight,
@@ -58229,7 +58503,7 @@ function renderNodes2(root, _defs, resolved, layout, palette, isDark, sizing, on
58229
58503
  activeTagGroup
58230
58504
  );
58231
58505
  const hasTagColor = tagColor !== void 0 && tagColor !== "#999999";
58232
- const tagBandFill = hasTagColor ? shapeFill(palette, tagColor, isDark, { solid }) : void 0;
58506
+ const tagBandFill = hasTagColor ? shapeFill(palette, tagColor, isDark, { mode: fillMode }) : void 0;
58233
58507
  const tagLabelColor = hasTagColor ? contrastText(
58234
58508
  tagBandFill,
58235
58509
  palette.textOnFillLight,
@@ -58655,7 +58929,7 @@ function tornadoBoxHeightFor(rows) {
58655
58929
  return rows.length * TORNADO_ROW_HEIGHT + 2 * CAPTION_BOX_PADDING_Y + CAPTION_HEADER_BAND_HEIGHT;
58656
58930
  }
58657
58931
  function renderTornadoBlock(svg, rows, args) {
58658
- const { x, y, width, height, palette, isDark } = args;
58932
+ const { x, y, width, height, palette, isDark, fillMode } = args;
58659
58933
  const { fill: fill2, stroke: chromeStroke } = analysisBlockChrome(palette, isDark);
58660
58934
  const labelColor = contrastText(
58661
58935
  fill2,
@@ -58698,7 +58972,7 @@ function renderTornadoBlock(svg, rows, args) {
58698
58972
  const rowY = firstRowY + i * TORNADO_ROW_HEIGHT;
58699
58973
  const labelY = rowY + TORNADO_ROW_HEIGHT / 2 + TORNADO_BAR_FONT_SIZE / 2 - 2;
58700
58974
  const barColor = bandColor(row.band, palette, palette.primary);
58701
- const barFill = shapeFill(palette, barColor, isDark);
58975
+ const barFill = fillMode === "outline" ? shapeFill(palette, barColor, isDark, { mode: "outline" }) : shapeFill(palette, barColor, isDark);
58702
58976
  const lowW = row.lowSwing * pixelsPerUnit;
58703
58977
  const highW = row.highSwing * pixelsPerUnit;
58704
58978
  const rowG = block.append("g").attr("class", "pert-tornado-row").attr("data-activity-id", row.id).attr("data-tornado-swing", String(row.lowSwing + row.highSwing));
@@ -59952,18 +60226,13 @@ function computeBarLabel(label, x1, barWidth, innerWidth, textColor, onFillColor
59952
60226
  }
59953
60227
  return null;
59954
60228
  }
59955
- function renderLabelBand(svg, y, leftMargin, color, palette, isDark, cssPrefix, dataAttr, solid, barH = BAR_H, bandRadius = BAND_RADIUS, bandAccentW = BAND_ACCENT_W) {
60229
+ function renderLabelBand(svg, y, leftMargin, color, palette, isDark, cssPrefix, dataAttr, fillMode, barH = BAR_H, bandRadius = BAND_RADIUS, bandAccentW = BAND_ACCENT_W) {
59956
60230
  const bandX = 5;
59957
60231
  const bandW = leftMargin - 7;
59958
60232
  const bandY = y - barH / 2;
59959
60233
  const clipId = `gantt-band-clip-${bandClipCounter++}`;
59960
60234
  svg.append("clipPath").attr("id", clipId).append("rect").attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", barH).attr("rx", bandRadius);
59961
- const tint2 = svg.append("rect").attr("class", `gantt-${cssPrefix}-band-bg`).attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", barH).attr("rx", bandRadius).attr(
59962
- "fill",
59963
- shapeFill(palette, color, isDark, {
59964
- ...solid !== void 0 && { solid }
59965
- })
59966
- ).style("pointer-events", "none");
60235
+ const tint2 = svg.append("rect").attr("class", `gantt-${cssPrefix}-band-bg`).attr("x", bandX).attr("y", bandY).attr("width", bandW).attr("height", barH).attr("rx", bandRadius).attr("fill", shapeFill(palette, color, isDark, { mode: fillMode })).style("pointer-events", "none");
59967
60236
  const accent = svg.append("rect").attr("class", `gantt-${cssPrefix}-band-accent`).attr("x", bandX).attr("y", bandY).attr("width", bandAccentW).attr("height", barH).attr("fill", color).attr("clip-path", `url(#${clipId})`).style("pointer-events", "none");
59968
60237
  if (dataAttr) {
59969
60238
  tint2.attr(dataAttr.key, dataAttr.value);
@@ -59979,7 +60248,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
59979
60248
  container.innerHTML = "";
59980
60249
  bandClipCounter = 0;
59981
60250
  if (resolved.tasks.length === 0) return;
59982
- const solid = false;
60251
+ const fillMode = void 0;
59983
60252
  const onClickItem = options?.onClickItem;
59984
60253
  const collapsedGroups = options?.collapsedGroups ?? new Set(resolved.groups.filter((g2) => g2.collapsed).map((g2) => g2.name));
59985
60254
  const onToggleGroup = options?.onToggleGroup;
@@ -60170,7 +60439,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60170
60439
  seriesColors2,
60171
60440
  palette
60172
60441
  );
60173
- const fillColor = shapeFill(palette, color, isDark, { solid });
60442
+ const fillColor = shapeFill(palette, color, isDark, { mode: fillMode });
60174
60443
  el.select("rect").attr("fill", fillColor).attr("stroke", color);
60175
60444
  });
60176
60445
  }
@@ -60271,7 +60540,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60271
60540
  isDark,
60272
60541
  "lane",
60273
60542
  { key: "data-lane", value: row.laneName },
60274
- solid,
60543
+ fillMode,
60275
60544
  sBarH,
60276
60545
  sBandRadius,
60277
60546
  sBandAccentW
@@ -60298,7 +60567,9 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60298
60567
  toggleIcon + " " + row.laneName + (row.aggregateProgress !== null ? ` ${Math.round(row.aggregateProgress)}%` : "")
60299
60568
  );
60300
60569
  if (laneBarWidth > 0) {
60301
- const barFill = shapeFill(palette, laneColor, isDark, { solid });
60570
+ const barFill = shapeFill(palette, laneColor, isDark, {
60571
+ mode: fillMode
60572
+ });
60302
60573
  const laneBandG = g.append("g").attr("class", "gantt-lane-band-group").attr("data-lane", row.laneName).on("mouseenter", () => {
60303
60574
  highlightLane(g, svg, row.tagKey, row.laneName);
60304
60575
  if (row.laneStartDate && row.laneEndDate) {
@@ -60344,7 +60615,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60344
60615
  isDark,
60345
60616
  "group",
60346
60617
  { key: "data-group", value: group.name },
60347
- solid,
60618
+ fillMode,
60348
60619
  sBarH,
60349
60620
  sBandRadius,
60350
60621
  sBandAccentW
@@ -60391,7 +60662,10 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60391
60662
  resetHighlight(g, svg);
60392
60663
  hideGanttDateIndicators(g);
60393
60664
  });
60394
- summaryG.append("rect").attr("x", gx1).attr("y", yOffset).attr("width", barWidth).attr("height", sBarH).attr("rx", 4).attr("fill", shapeFill(palette, groupColor, isDark, { solid })).attr("stroke", groupColor).attr("stroke-width", 2);
60665
+ summaryG.append("rect").attr("x", gx1).attr("y", yOffset).attr("width", barWidth).attr("height", sBarH).attr("rx", 4).attr(
60666
+ "fill",
60667
+ shapeFill(palette, groupColor, isDark, { mode: fillMode })
60668
+ ).attr("stroke", groupColor).attr("stroke-width", 2);
60395
60669
  if (group.progress !== null && group.progress > 0) {
60396
60670
  summaryG.append("rect").attr("x", gx1).attr("y", yOffset).attr("width", barWidth * Math.min(group.progress / 100, 1)).attr("height", sBarH).attr("fill", groupColor).attr("opacity", 0.5);
60397
60671
  }
@@ -60403,7 +60677,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60403
60677
  innerWidth,
60404
60678
  palette.text,
60405
60679
  contrastText(
60406
- shapeFill(palette, groupColor, isDark, { solid }),
60680
+ shapeFill(palette, groupColor, isDark, { mode: fillMode }),
60407
60681
  palette.textOnFillLight,
60408
60682
  palette.textOnFillDark
60409
60683
  ),
@@ -60421,7 +60695,9 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60421
60695
  });
60422
60696
  } else {
60423
60697
  const groupBarWidth = Math.max(gx2 - gx1, 2);
60424
- const bandFill = shapeFill(palette, groupColor, isDark, { solid });
60698
+ const bandFill = shapeFill(palette, groupColor, isDark, {
60699
+ mode: fillMode
60700
+ });
60425
60701
  const groupBarG = g.append("g").attr("class", "gantt-group-bar").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).on("mouseenter", () => {
60426
60702
  highlightGroup(g, svg, group.name);
60427
60703
  showGanttDateIndicators(
@@ -60448,7 +60724,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60448
60724
  innerWidth,
60449
60725
  palette.text,
60450
60726
  contrastText(
60451
- shapeFill(palette, groupColor, isDark, { solid }),
60727
+ shapeFill(palette, groupColor, isDark, { mode: fillMode }),
60452
60728
  palette.textOnFillLight,
60453
60729
  palette.textOnFillDark
60454
60730
  ),
@@ -60528,7 +60804,9 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60528
60804
  const x1 = xScale(tStart);
60529
60805
  const x2 = xScale(tEnd);
60530
60806
  const barWidth = Math.max(x2 - x1, 2);
60531
- const fillColor = shapeFill(palette, barColor, isDark, { solid });
60807
+ const fillColor = shapeFill(palette, barColor, isDark, {
60808
+ mode: fillMode
60809
+ });
60532
60810
  const taskG = g.append("g").attr("class", "gantt-task").attr("data-line-number", String(task.lineNumber)).attr("data-task-name", task.label).attr("data-task-id", task.id).attr("data-group", topGroup).style("cursor", onClickItem ? "pointer" : "default").on("click", () => {
60533
60811
  if (onClickItem) onClickItem(task.lineNumber);
60534
60812
  }).on("mouseenter", () => {
@@ -60599,7 +60877,7 @@ function renderGantt(container, resolved, palette, isDark, options, exportDims)
60599
60877
  innerWidth,
60600
60878
  palette.text,
60601
60879
  contrastText(
60602
- shapeFill(palette, barColor, isDark, { solid }),
60880
+ shapeFill(palette, barColor, isDark, { mode: fillMode }),
60603
60881
  palette.textOnFillLight,
60604
60882
  palette.textOnFillDark
60605
60883
  ),
@@ -61990,11 +62268,9 @@ import * as d3Selection24 from "d3-selection";
61990
62268
  function stateDefaultColor(palette, colorOff) {
61991
62269
  return colorOff ? palette.textMuted : palette.colors.blue;
61992
62270
  }
61993
- function stateFill(palette, isDark, nodeColor2, colorOff, solid) {
62271
+ function stateFill(palette, isDark, nodeColor2, colorOff, fillMode) {
61994
62272
  const color = nodeColor2 ?? stateDefaultColor(palette, colorOff);
61995
- return shapeFill(palette, color, isDark, {
61996
- ...solid !== void 0 && { solid }
61997
- });
62273
+ return shapeFill(palette, color, isDark, { mode: fillMode });
61998
62274
  }
61999
62275
  function stateStroke(palette, nodeColor2, colorOff) {
62000
62276
  return nodeColor2 ?? stateDefaultColor(palette, colorOff);
@@ -62080,7 +62356,8 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
62080
62356
  const gy = group.y - sGroupExtraPadding - sGroupLabelFontSize - 4;
62081
62357
  const gw = group.width + sGroupExtraPadding * 2;
62082
62358
  const gh = group.height + sGroupExtraPadding * 2 + sGroupLabelFontSize + 4;
62083
- const fillColor = group.color ? mix(group.color, themeBaseBg(palette, isDark), 10) : isDark ? palette.surface : mix(palette.border, palette.bg, 30);
62359
+ const groupOutline = fillModeFromOptions(graph.options ?? {}) === "outline";
62360
+ const fillColor = groupOutline ? themeBaseBg(palette, isDark) : group.color ? mix(group.color, themeBaseBg(palette, isDark), 10) : isDark ? palette.surface : mix(palette.border, palette.bg, 30);
62084
62361
  const strokeColor = group.color ?? palette.textMuted;
62085
62362
  const groupWrapper = contentG.append("g").attr("class", "st-group-wrapper").attr("data-line-number", String(group.lineNumber)).attr("data-group-id", group.id).attr("data-group-toggle", group.id).attr("tabindex", "0").attr("role", "button").attr("aria-expanded", "true").attr("aria-label", `Collapse group ${group.label}`).style("cursor", "pointer");
62086
62363
  groupWrapper.append("rect").attr("x", gx).attr("y", gy).attr("width", gw).attr("height", gh).attr("rx", 6).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("class", "st-group");
@@ -62174,7 +62451,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
62174
62451
  if (group.collapsed) collapsedGroupIds.add(group.id);
62175
62452
  }
62176
62453
  const colorOff = graph.options?.["color"] === "off";
62177
- const solid = graph.options?.["solid-fill"] === "on";
62454
+ const fillMode = fillModeFromOptions(graph.options ?? {});
62178
62455
  const noNotes = graph.options?.["no-notes"] === "on";
62179
62456
  for (const node of layout.nodes) {
62180
62457
  const isCollapsedGroup = collapsedGroupIds.has(node.id);
@@ -62194,7 +62471,9 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
62194
62471
  const w = node.width;
62195
62472
  const h = node.height;
62196
62473
  const groupColor = node.color ?? stateDefaultColor(palette, colorOff);
62197
- const fillColor = shapeFill(palette, groupColor, isDark, { solid });
62474
+ const fillColor = shapeFill(palette, groupColor, isDark, {
62475
+ mode: fillMode
62476
+ });
62198
62477
  const strokeColor = groupColor;
62199
62478
  const COLLAPSE_BAR_H = 6;
62200
62479
  nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", sStateCornerRadius).attr("ry", sStateCornerRadius).attr("fill", fillColor).attr("stroke", strokeColor).attr("stroke-width", sNodeStrokeWidth);
@@ -62217,7 +62496,7 @@ function renderState(container, graph, layout, palette, isDark, onClickItem, exp
62217
62496
  isDark,
62218
62497
  node.color,
62219
62498
  colorOff,
62220
- solid
62499
+ fillMode
62221
62500
  );
62222
62501
  nodeG.append("rect").attr("x", -w / 2).attr("y", -h / 2).attr("width", w).attr("height", h).attr("rx", sStateCornerRadius).attr("ry", sStateCornerRadius).attr("fill", resolvedFill).attr("stroke", stateStroke(palette, node.color, colorOff)).attr("stroke-width", sNodeStrokeWidth);
62223
62502
  nodeG.append("text").attr("x", 0).attr("y", 0).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr(
@@ -62306,6 +62585,7 @@ var DIAGRAM_PADDING13, MAX_SCALE7, NODE_FONT_SIZE7, EDGE_LABEL_FONT_SIZE12, GROU
62306
62585
  var init_state_renderer = __esm({
62307
62586
  "src/graph/state-renderer.ts"() {
62308
62587
  "use strict";
62588
+ init_parsing();
62309
62589
  init_arrow_markers();
62310
62590
  init_fit_canvas();
62311
62591
  init_fonts();
@@ -62802,7 +63082,7 @@ function clearDim(root) {
62802
63082
  function renderHtmlPanel(panel, parsed, quadrant, qColor, palette, isDark, rootContainer, onClickItem) {
62803
63083
  const ringOrder = parsed.rings.map((r) => r.name);
62804
63084
  const fillColor = shapeFill(palette, qColor, isDark, {
62805
- solid: parsed.options["solid-fill"] === "on"
63085
+ mode: fillModeFromOptions(parsed.options)
62806
63086
  });
62807
63087
  let expandedLineNum = null;
62808
63088
  function render2() {
@@ -63040,6 +63320,7 @@ var BLIP_RADIUS, BLIP_FONT_SIZE, TITLE_FONT_SIZE3, NARROW_BREAKPOINT;
63040
63320
  var init_interactive = __esm({
63041
63321
  "src/tech-radar/interactive.ts"() {
63042
63322
  "use strict";
63323
+ init_parsing();
63043
63324
  init_fonts();
63044
63325
  init_color_utils();
63045
63326
  init_layout15();
@@ -63327,7 +63608,7 @@ function renderTechRadar(container, parsed, palette, isDark, onClickItem, export
63327
63608
  // Tech-radar opts out of solid-fill: blip popover stays in tinted
63328
63609
  // form so it reads consistently against the radar bg regardless of
63329
63610
  // the diagram's option setting.
63330
- false
63611
+ void 0
63331
63612
  );
63332
63613
  showBlipHighlight(lineNum, bx, by, blipGroup);
63333
63614
  }).on("mousemove", (event) => {
@@ -63356,7 +63637,7 @@ function renderTechRadar(container, parsed, palette, isDark, onClickItem, export
63356
63637
  // Tech-radar opts out of solid-fill: blip popover stays in tinted
63357
63638
  // form so it reads consistently against the radar bg regardless of
63358
63639
  // the diagram's option setting.
63359
- false
63640
+ void 0
63360
63641
  );
63361
63642
  popover.style.pointerEvents = "auto";
63362
63643
  showBlipHighlight(lineNum, bx, by, blipGroup);
@@ -63400,7 +63681,7 @@ function renderTechRadar(container, parsed, palette, isDark, onClickItem, export
63400
63681
  // Tech-radar opts out of solid-fill: blip popover stays in tinted
63401
63682
  // form so it reads consistently against the radar bg regardless of
63402
63683
  // the diagram's option setting.
63403
- false
63684
+ void 0
63404
63685
  );
63405
63686
  }
63406
63687
  const lineNum = String(blip.lineNumber);
@@ -63593,10 +63874,8 @@ function createBlipPopover(container, _palette, isDark) {
63593
63874
  container.appendChild(el);
63594
63875
  return el;
63595
63876
  }
63596
- function showBlipPopover(popover, blip, qColor, palette, isDark, event, solid) {
63597
- const fillColor = shapeFill(palette, qColor, isDark, {
63598
- ...solid !== void 0 && { solid }
63599
- });
63877
+ function showBlipPopover(popover, blip, qColor, palette, isDark, event, fillMode) {
63878
+ const fillColor = shapeFill(palette, qColor, isDark, { mode: fillMode });
63600
63879
  const hasDesc = blip.description.length > 0;
63601
63880
  const onFillText = contrastText(
63602
63881
  fillColor,
@@ -63963,7 +64242,7 @@ function layoutJourneyMap(parsed, palette, options) {
63963
64242
  palette,
63964
64243
  scoreToColor(avgScore, palette),
63965
64244
  isDark,
63966
- { solid: parsed.options["solid-fill"] === "on" }
64245
+ { mode: fillModeFromOptions(parsed.options) }
63967
64246
  );
63968
64247
  const COLLAPSED_CARD_H = 26;
63969
64248
  const COLLAPSED_GAP = 6;
@@ -64037,6 +64316,7 @@ var PADDING, TITLE_HEIGHT7, PERSONA_HEIGHT, PERSONA_PANEL_WIDTH, HEADER_GAP, CUR
64037
64316
  var init_layout16 = __esm({
64038
64317
  "src/journey-map/layout.ts"() {
64039
64318
  "use strict";
64319
+ init_parsing();
64040
64320
  init_color_utils();
64041
64321
  init_text_measure();
64042
64322
  PADDING = 24;
@@ -64078,7 +64358,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64078
64358
  const onActiveTagGroupChange = options?.onActiveTagGroupChange;
64079
64359
  const collapsedPhases = options?.collapsedPhases ?? /* @__PURE__ */ new Set();
64080
64360
  const onPhaseToggle = options?.onPhaseToggle;
64081
- const solid = parsed.options["solid-fill"] === "on";
64361
+ const fillMode = fillModeFromOptions(parsed.options);
64082
64362
  const layout = layoutJourneyMap(parsed, palette, {
64083
64363
  collapsedPhases,
64084
64364
  ...exportDims !== void 0 && { exportDims },
@@ -64133,7 +64413,9 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64133
64413
  const textX = panelX + CARD_PADDING_X3;
64134
64414
  const clipId = "persona-clip";
64135
64415
  defs.append("clipPath").attr("id", clipId).append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS);
64136
- const personaFill = shapeFill(palette, personaColor, isDark, { solid });
64416
+ const personaFill = shapeFill(palette, personaColor, isDark, {
64417
+ mode: fillMode
64418
+ });
64137
64419
  const onPersonaText = contrastText(
64138
64420
  personaFill,
64139
64421
  palette.textOnFillLight,
@@ -64141,12 +64423,21 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64141
64423
  );
64142
64424
  personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", personaFill);
64143
64425
  if (descLines.length > 0) {
64144
- personaG.append("line").attr("x1", panelX + 1).attr("x2", panelX + panelWidth - silhouetteZone).attr("y1", panelY + titleRowH).attr("y2", panelY + titleRowH).attr("stroke", solid ? onPersonaText : personaColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
64426
+ personaG.append("line").attr("x1", panelX + 1).attr("x2", panelX + panelWidth - silhouetteZone).attr("y1", panelY + titleRowH).attr("y2", panelY + titleRowH).attr("stroke", fillMode === "solid" ? onPersonaText : personaColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
64145
64427
  }
64146
64428
  const silX = panelX + panelWidth - 32;
64147
64429
  const silY = panelY + panelHeight / 2 - 6;
64148
64430
  const silClip = personaG.append("g").attr("clip-path", `url(#${clipId})`);
64149
- renderPersonaSilhouette(silClip, silX, silY, personaColor, palette, 1.2);
64431
+ renderPersonaSilhouette(
64432
+ silClip,
64433
+ silX,
64434
+ silY,
64435
+ personaColor,
64436
+ palette,
64437
+ isDark,
64438
+ 1.2,
64439
+ fillMode
64440
+ );
64150
64441
  personaG.append("rect").attr("x", panelX).attr("y", panelY).attr("width", panelWidth).attr("height", panelHeight).attr("rx", CARD_RADIUS).attr("fill", "none").attr("stroke", personaColor).attr("stroke-width", CARD_STROKE_WIDTH2);
64151
64442
  personaG.append("text").attr("x", textX).attr("y", panelY + CARD_PADDING_Y3 + FONT_SIZE_STEP).attr("font-size", FONT_SIZE_STEP).attr("font-weight", "500").attr("fill", onPersonaText).text(parsed.persona.name);
64152
64443
  for (let li = 0; li < descLines.length; li++) {
@@ -64282,7 +64573,9 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64282
64573
  pt.y,
64283
64574
  pt.score,
64284
64575
  palette,
64285
- isDark
64576
+ isDark,
64577
+ void 0,
64578
+ fillMode
64286
64579
  );
64287
64580
  addEmotionLabel(faceG, pt, palette);
64288
64581
  if (step) {
@@ -64315,7 +64608,9 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64315
64608
  pt.y,
64316
64609
  pt.score,
64317
64610
  palette,
64318
- isDark
64611
+ isDark,
64612
+ void 0,
64613
+ fillMode
64319
64614
  );
64320
64615
  addEmotionLabel(faceG, pt, palette);
64321
64616
  if (step) {
@@ -64400,7 +64695,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64400
64695
  palette,
64401
64696
  stepColor ?? palette.primary,
64402
64697
  isDark,
64403
- { solid }
64698
+ { mode: fillMode }
64404
64699
  );
64405
64700
  const rowStroke = stepColor ?? palette.textMuted;
64406
64701
  itemG.append("rect").attr("x", listX).attr("y", itemY).attr("width", cardW).attr("height", COLLAPSED_CARD_H).attr("rx", CARD_RADIUS).attr("fill", rowFill).attr("stroke", rowStroke).attr("stroke-width", CARD_STROKE_WIDTH2);
@@ -64414,7 +64709,8 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64414
64709
  step.score,
64415
64710
  palette,
64416
64711
  isDark,
64417
- COLLAPSED_FACE_R
64712
+ COLLAPSED_FACE_R,
64713
+ fillMode
64418
64714
  );
64419
64715
  faceG.attr("data-line-number", step.lineNumber);
64420
64716
  faceG.attr("data-score", step.score);
@@ -64443,7 +64739,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64443
64739
  effectiveActiveGroup,
64444
64740
  parsed.tagGroups,
64445
64741
  onNavigateToLine,
64446
- solid
64742
+ fillMode
64447
64743
  );
64448
64744
  }
64449
64745
  }
@@ -64458,7 +64754,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64458
64754
  effectiveActiveGroup,
64459
64755
  parsed.tagGroups,
64460
64756
  onNavigateToLine,
64461
- solid
64757
+ fillMode
64462
64758
  );
64463
64759
  }
64464
64760
  }
@@ -64532,7 +64828,7 @@ function renderJourneyMap(container, parsed, palette, isDark, options) {
64532
64828
  );
64533
64829
  const by = Math.max(PADDING2, fcy - FACE_HOVER_R - THOUGHT_GAP - bh);
64534
64830
  const scoreColor = scoreToColor(score, palette);
64535
- const tintedBg = mix(scoreColor, palette.surface, 20);
64831
+ const tintedBg = fillMode === "outline" ? themeBaseBg(palette, isDark) : mix(scoreColor, palette.surface, 20);
64536
64832
  const g = overlayG.append("g").attr("class", "journey-thought-hover");
64537
64833
  g.append("rect").attr("x", bx).attr("y", by).attr("width", bw).attr("height", bh).attr("rx", CARD_RADIUS).attr("fill", tintedBg).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
64538
64834
  g.append("line").attr("x1", fcx).attr("y1", by + bh).attr("x2", fcx).attr("y2", fcy - FACE_HOVER_R - 1).attr("stroke", scoreColor).attr("stroke-width", CARD_STROKE_WIDTH2);
@@ -64626,7 +64922,7 @@ function resolveStepColor(step, scoreColor, activeGroup, tagGroups, _palette) {
64626
64922
  );
64627
64923
  return entry?.color;
64628
64924
  }
64629
- function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onNavigateToLine, solid) {
64925
+ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onNavigateToLine, fillMode) {
64630
64926
  const stepG = parent.append("g").attr("class", "journey-step").attr("data-line-number", sl.step.lineNumber);
64631
64927
  if (sl.step.score !== void 0) {
64632
64928
  stepG.attr("data-score", sl.step.score);
@@ -64647,7 +64943,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
64647
64943
  palette,
64648
64944
  resolvedColor ?? palette.primary,
64649
64945
  isDark,
64650
- { ...solid !== void 0 && { solid } }
64946
+ { mode: fillMode }
64651
64947
  );
64652
64948
  const cardStroke = resolvedColor ?? palette.textMuted;
64653
64949
  const onCardText = contrastText(
@@ -64665,7 +64961,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
64665
64961
  const cardAnnotations = sl.step.annotations;
64666
64962
  const hasContent = sl.step.description || cardAnnotations.length > 0;
64667
64963
  if (hasContent) {
64668
- stepG.append("line").attr("x1", cx).attr("y1", cy + titleBlockH).attr("x2", cx + sl.width).attr("y2", cy + titleBlockH).attr("stroke", solid ? onCardText : cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
64964
+ stepG.append("line").attr("x1", cx).attr("y1", cy + titleBlockH).attr("x2", cx + sl.width).attr("y2", cy + titleBlockH).attr("stroke", fillMode === "solid" ? onCardText : cardStroke).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
64669
64965
  }
64670
64966
  let metaY = cy + titleBlockH + CARD_META_LINE_HEIGHT3;
64671
64967
  if (sl.step.description) {
@@ -64687,7 +64983,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
64687
64983
  const annoColor = annotationColor(anno.type, palette);
64688
64984
  const iconPaths = annotationIconPaths(anno.type);
64689
64985
  const annoLines = wrapText2(anno.text, annoTextW, FONT_SIZE_META);
64690
- const iconColor = solid ? onCardText : annoColor;
64986
+ const iconColor = fillMode === "solid" ? onCardText : annoColor;
64691
64987
  renderAnnotationIcon(
64692
64988
  stepG,
64693
64989
  cx + CARD_PADDING_X3,
@@ -64712,7 +65008,7 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
64712
65008
  const TAG_GAP = 6;
64713
65009
  const stripY = cy - TAG_STRIP_HEIGHT - TAG_GAP;
64714
65010
  const stripFill = shapeFill(palette, stripColor, isDark, {
64715
- ...solid !== void 0 && { solid }
65011
+ mode: fillMode
64716
65012
  });
64717
65013
  stepG.append("rect").attr("x", cx).attr("y", stripY).attr("width", sl.width).attr("height", TAG_STRIP_HEIGHT).attr("rx", CARD_RADIUS).attr("fill", stripFill).attr("stroke", stripColor).attr("stroke-width", CARD_STROKE_WIDTH2);
64718
65014
  const stripTextColor = contrastText(
@@ -64729,8 +65025,8 @@ function renderStepCard(parent, sl, palette, isDark, activeGroup, tagGroups, onN
64729
65025
  });
64730
65026
  }
64731
65027
  }
64732
- function renderPersonaSilhouette(parent, cx, cy, color, palette, scale = 1) {
64733
- const fill2 = mix(color, palette.bg, 70);
65028
+ function renderPersonaSilhouette(parent, cx, cy, color, palette, isDark, scale = 1, fillMode) {
65029
+ const fill2 = fillMode === "outline" ? themeBaseBg(palette, isDark) : mix(color, palette.bg, 70);
64734
65030
  const stroke2 = color;
64735
65031
  const s = scale;
64736
65032
  parent.append("path").attr(
@@ -64742,12 +65038,12 @@ function renderPersonaSilhouette(parent, cx, cy, color, palette, scale = 1) {
64742
65038
  `M ${cx} ${cy - 12 * s} C ${cx + 10 * s} ${cy - 12 * s}, ${cx + 9 * s} ${cy + 2 * s}, ${cx + 6 * s} ${cy + 6 * s} Q ${cx} ${cy + 9 * s}, ${cx - 6 * s} ${cy + 6 * s} C ${cx - 9 * s} ${cy + 2 * s}, ${cx - 10 * s} ${cy - 12 * s}, ${cx} ${cy - 12 * s} Z`
64743
65039
  ).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.2);
64744
65040
  }
64745
- function renderScoreFace(parent, cx, cy, score, palette, isDark, radius) {
65041
+ function renderScoreFace(parent, cx, cy, score, palette, isDark, radius, fillMode) {
64746
65042
  const r = radius ?? FACE_RADIUS;
64747
65043
  const color = scoreToColor(score, palette);
64748
65044
  const g = parent.append("g").attr("class", "journey-face").attr("data-cx", cx).attr("data-cy", cy);
64749
65045
  const iconG = g.append("g").attr("class", "journey-face-icon");
64750
- const faceFill = shapeFill(palette, color, isDark);
65046
+ const faceFill = fillMode === "outline" ? shapeFill(palette, color, isDark, { mode: "outline" }) : shapeFill(palette, color, isDark);
64751
65047
  iconG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r + 1).attr("fill", palette.bg);
64752
65048
  iconG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", faceFill).attr("stroke", color).attr("stroke-width", 2);
64753
65049
  const eyeColor = color;
@@ -64835,6 +65131,7 @@ var init_renderer21 = __esm({
64835
65131
  "src/journey-map/renderer.ts"() {
64836
65132
  "use strict";
64837
65133
  init_tag_groups();
65134
+ init_parsing();
64838
65135
  init_color_utils();
64839
65136
  init_fonts();
64840
65137
  init_parser28();
@@ -65545,7 +65842,7 @@ __export(renderer_exports21, {
65545
65842
  import * as d3Selection27 from "d3-selection";
65546
65843
  function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims, viewState, renderOptions) {
65547
65844
  if (parsed.nodes.length === 0) return;
65548
- const solid = parsed.options?.["solid-fill"] === "on";
65845
+ const fillMode = fillModeFromOptions(parsed.options ?? {});
65549
65846
  d3Selection27.select(container).selectAll(":not([data-d3-tooltip])").remove();
65550
65847
  const width = exportDims?.width ?? container.clientWidth;
65551
65848
  const height = exportDims?.height ?? container.clientHeight;
@@ -65682,7 +65979,9 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
65682
65979
  const ln = layout.nodes[i];
65683
65980
  const node = parsed.nodes[i];
65684
65981
  const solidColor = resolveNodeColor5(node.color, palette, defaultNodeColor);
65685
- const fillColor = shapeFill(palette, solidColor, isDark, { solid });
65982
+ const fillColor = shapeFill(palette, solidColor, isDark, {
65983
+ mode: fillMode
65984
+ });
65686
65985
  const textColor = contrastText(
65687
65986
  fillColor,
65688
65987
  palette.textOnFillLight,
@@ -65726,7 +66025,7 @@ function renderCycle(container, parsed, palette, isDark, onClickItem, exportDims
65726
66025
  const labelText = nodeG.append("text").attr("x", ln.x).attr("y", headerCenterY + scaledNodeFont / 3).attr("text-anchor", "middle").attr("fill", textColor).attr("font-family", FONT_FAMILY).attr("font-size", scaledNodeFont).attr("font-weight", "600");
65727
66026
  renderInlineText(labelText, node.label, palette, scaledNodeFont);
65728
66027
  const sepY = ln.y - nodeH / 2 + HEADER_H2;
65729
- nodeG.append("line").attr("x1", ln.x - nodeW / 2).attr("y1", sepY).attr("x2", ln.x + nodeW / 2).attr("y2", sepY).attr("stroke", solid ? descColor : solidColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
66028
+ nodeG.append("line").attr("x1", ln.x - nodeW / 2).attr("y1", sepY).attr("x2", ln.x + nodeW / 2).attr("y2", sepY).attr("stroke", fillMode === "solid" ? descColor : solidColor).attr("stroke-opacity", 0.3).attr("stroke-width", 1);
65730
66029
  const descStartY = sepY + 4 + scaledDescFont;
65731
66030
  const descPadX = Math.max(8, 12 * layout.scale);
65732
66031
  const descX = ln.x - nodeW / 2 + descPadX;
@@ -65829,6 +66128,7 @@ var NODE_FONT_SIZE8, DESC_FONT_SIZE7, EDGE_LABEL_FONT_SIZE14, DESC_LINE_HEIGHT8,
65829
66128
  var init_renderer22 = __esm({
65830
66129
  "src/cycle/renderer.ts"() {
65831
66130
  "use strict";
66131
+ init_parsing();
65832
66132
  init_fonts();
65833
66133
  init_title_constants();
65834
66134
  init_legend_constants();
@@ -67086,7 +67386,6 @@ function renderClockCards(gCards, layout, resolved, palette, isDark, now, frameW
67086
67386
  const hasCoords = Number.isFinite(poi.lat) && Number.isFinite(poi.lon);
67087
67387
  const isFixed = poi.tzFixedOffsetMin !== void 0;
67088
67388
  const sun = !isFixed && hasCoords ? sunLine(now, poi.lat, poi.lon) : null;
67089
- const up = sun ? sun.up : parts.h >= 6 && parts.h < 18;
67090
67389
  const ts = formatTime(parts.h, parts.m, parts.s, hours12);
67091
67390
  const status = workStatus(parts, work);
67092
67391
  const viewerWeekday = WEEKDAY_ABBR3[new Date(now).getDay()];
@@ -67094,16 +67393,17 @@ function renderClockCards(gCards, layout, resolved, palette, isDark, now, frameW
67094
67393
  const line22 = [showWeekday ? parts.weekday : null, status?.text].filter(Boolean).join(" \xB7 ");
67095
67394
  const mainFont = 18;
67096
67395
  const sf = 8;
67097
- const mainW = measureText(ts.main, mainFont);
67098
- const stackW = Math.max(
67099
- measureText(`:${ts.sec}`, sf),
67100
- ts.ap ? measureText(ts.ap, sf) : 0
67101
- );
67102
- const stackGap = 3;
67103
- const dotGap = 15;
67396
+ const advance = (s, f) => [...s].reduce((w, c) => w + f * (c === ":" ? 0.334 : 0.6), 0);
67397
+ const mainW = advance(ts.main, mainFont);
67398
+ const secW = advance(`:${ts.sec}`, sf);
67399
+ const stackW = Math.max(secW, ts.ap ? measureText(ts.ap, sf) : 0);
67400
+ const stackGap = 6;
67104
67401
  const padX = 9;
67105
- const line1W = dotGap + mainW + stackGap + stackW;
67106
- const line2W = measureText(line22, 10.5);
67402
+ const iconR = 3.5;
67403
+ const iconGap = 5;
67404
+ const line2Icon = status ? iconR * 2 + iconGap : 0;
67405
+ const line1W = mainW + stackGap + stackW;
67406
+ const line2W = line2Icon + measureText(line22, 10.5);
67107
67407
  const cardW = Math.max(line1W, line2W) + padX * 2;
67108
67408
  const cardH = 44;
67109
67409
  const leaderGap = 7;
@@ -67133,27 +67433,19 @@ function renderClockCards(gCards, layout, resolved, palette, isDark, now, frameW
67133
67433
  const leaderX = clamp(cx, cardLeft + 10, cardLeft + cardW - 10);
67134
67434
  g.append("line").attr("x1", cx).attr("y1", below ? lp.cy + lp.r : lp.cy - lp.r).attr("x2", leaderX).attr("y2", below ? cardTop : cardTop + cardH).attr("stroke", border).attr("stroke-width", 1);
67135
67435
  g.append("rect").attr("x", cardLeft).attr("y", cardTop).attr("width", cardW).attr("height", cardH).attr("rx", 6).attr("fill", cardFill).attr("stroke", border).attr("stroke-width", 1);
67136
- const dotCX = cardLeft + padX + 3.5;
67436
+ const statusColor = (cls) => cls === "ok" ? sw.ok : cls === "soon" ? sw.soon : sw.off;
67137
67437
  const line1Y = cardTop + 20;
67138
- const dot = g.append("circle").attr("data-dgmo-clock-status-dot", "").attr("cx", dotCX).attr("cy", line1Y - mainFont * 0.35).attr("r", 3.5);
67139
- if (status) {
67140
- const dc = status.cls === "ok" ? sw.ok : status.cls === "soon" ? sw.soon : sw.off;
67141
- if (status.cls === "off") {
67142
- dot.attr("fill", "none").attr("stroke", dc).attr("stroke-width", 1.4);
67143
- } else {
67144
- dot.attr("fill", dc);
67145
- }
67146
- } else {
67147
- dot.attr("fill", up ? sw.day : sw.night);
67148
- }
67149
- const timeX = cardLeft + padX + dotGap;
67150
- g.append("text").attr("data-dgmo-clock-digital-part", "main").attr("x", timeX).attr("y", line1Y).attr("font-family", FONT_FAMILY).attr("fill", palette.text).attr("font-size", mainFont).attr("font-weight", 600).style("font-variant-numeric", "tabular-nums").text(ts.main);
67438
+ const timeX = cardLeft + padX;
67439
+ g.append("text").attr("data-dgmo-clock-digital-part", "main").attr("x", timeX).attr("y", line1Y).attr("font-family", FONT_FAMILY).attr("fill", palette.text).attr("font-size", mainFont).attr("font-weight", 600).attr("textLength", mainW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(ts.main);
67151
67440
  const stackX = timeX + mainW + stackGap;
67152
67441
  const capTop = line1Y - mainFont * 0.7;
67153
- g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", capTop + sf * 0.72).attr("font-family", FONT_FAMILY).attr("fill", muted).attr("font-size", sf).style("font-variant-numeric", "tabular-nums").text(`:${ts.sec}`);
67442
+ g.append("text").attr("data-dgmo-clock-digital-part", "sec").attr("x", stackX).attr("y", capTop + sf * 0.72).attr("font-family", FONT_FAMILY).attr("fill", muted).attr("font-size", sf).attr("textLength", secW).attr("lengthAdjust", "spacing").style("font-variant-numeric", "tabular-nums").text(`:${ts.sec}`);
67154
67443
  g.append("text").attr("data-dgmo-clock-digital-part", "ap").attr("x", stackX).attr("y", line1Y).attr("font-family", FONT_FAMILY).attr("fill", muted).attr("font-size", sf).text(ts.ap);
67155
67444
  const line2Y = cardTop + 36;
67156
- const l2 = g.append("text").attr("x", cardLeft + padX).attr("y", line2Y).attr("font-family", FONT_FAMILY).attr("font-size", 10.5).attr("fill", muted);
67445
+ if (status) {
67446
+ g.append("circle").attr("data-dgmo-clock-status-icon", "").attr("cx", cardLeft + padX + iconR).attr("cy", line2Y - 3.5).attr("r", iconR).attr("fill", statusColor(status.cls));
67447
+ }
67448
+ const l2 = g.append("text").attr("x", cardLeft + padX + line2Icon).attr("y", line2Y).attr("font-family", FONT_FAMILY).attr("font-size", 10.5).attr("fill", muted);
67157
67449
  let needSep = false;
67158
67450
  if (showWeekday) {
67159
67451
  l2.append("tspan").text(parts.weekday);
@@ -71269,7 +71561,7 @@ function renderPyramid(container, parsed, palette, isDark, onClickItem, exportDi
71269
71561
  ].map((p) => `${p[0]},${p[1]}`).join(" ");
71270
71562
  const solidColor = resolveSolid(layer, i);
71271
71563
  const fillColor = shapeFill(palette, solidColor, isDark, {
71272
- solid: parsed.options["solid-fill"] === "on"
71564
+ mode: fillModeFromOptions(parsed.options)
71273
71565
  });
71274
71566
  const layerG = diagramG.append("g").attr("class", "pyramid-layer").attr("data-line-number", layer.lineNumber);
71275
71567
  if (onClickItem) {
@@ -71576,6 +71868,7 @@ var TITLE_AREA_HEIGHT2, H_MARGIN_FRAC, V_MARGIN, BASE_WIDTH_FRAC_NO_DESC, PYRAMI
71576
71868
  var init_renderer24 = __esm({
71577
71869
  "src/pyramid/renderer.ts"() {
71578
71870
  "use strict";
71871
+ init_parsing();
71579
71872
  init_fonts();
71580
71873
  init_title_constants();
71581
71874
  init_color_utils();
@@ -71665,10 +71958,10 @@ function renderRing(container, parsed, palette, isDark, onClickItem, exportDims)
71665
71958
  }
71666
71959
  return seriesColors2[i % seriesColors2.length];
71667
71960
  };
71668
- const solid = parsed.options["solid-fill"] === "on";
71961
+ const fillMode = fillModeFromOptions(parsed.options);
71669
71962
  const layerColors = parsed.layers.map((l, i) => resolveLayerColor(l, i));
71670
71963
  const layerFills = layerColors.map(
71671
- (c) => shapeFill(palette, c, isDark, { solid })
71964
+ (c) => shapeFill(palette, c, isDark, { mode: fillMode })
71672
71965
  );
71673
71966
  const diagramG = svg.append("g").attr("class", "ring-body");
71674
71967
  const strokeColor = palette.text;
@@ -71854,6 +72147,7 @@ var TITLE_AREA_HEIGHT3, H_MARGIN_FRAC2, V_MARGIN2, RING_AREA_FRAC_NO_DESC, RING_
71854
72147
  var init_renderer25 = __esm({
71855
72148
  "src/ring/renderer.ts"() {
71856
72149
  "use strict";
72150
+ init_parsing();
71857
72151
  init_fonts();
71858
72152
  init_title_constants();
71859
72153
  init_color_utils();
@@ -72547,14 +72841,13 @@ function renderTreemapForExport(container, parsed, palette, isDark, exportDims,
72547
72841
  }
72548
72842
  function renderTreemap(container, parsed, palette, isDark, exportDims, options = {}) {
72549
72843
  if (parsed.error || parsed.roots.length === 0) return;
72550
- void isDark;
72551
72844
  d3Selection32.select(container).selectAll(":not([data-d3-tooltip])").remove();
72552
72845
  const width = exportDims?.width ?? container.clientWidth;
72553
72846
  const height = exportDims?.height ?? container.clientHeight;
72554
72847
  if (width <= 0 || height <= 0) return;
72555
72848
  const mode = resolveColorMode(parsed, options.colorMode);
72556
72849
  const opts = parsed.options;
72557
- const solid = opts.solidFill;
72850
+ const fillMode = opts.fillMode;
72558
72851
  const exportMode = options.exportMode ?? false;
72559
72852
  const seriesColorsTop = getSeriesColors(palette);
72560
72853
  const showTitle = !!parsed.title;
@@ -72607,7 +72900,7 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
72607
72900
  const h = Math.max(0, cell.y1 - cell.y0);
72608
72901
  if (w <= 0 || h <= 0) continue;
72609
72902
  const baseColor2 = resolveCellColor(cell, colorCtx);
72610
- const fill2 = cell.isContainer ? baseColor2 : solid ? baseColor2 : mix(baseColor2, palette.bg, LEAF_MUTE_PCT);
72903
+ const fill2 = fillMode === "outline" ? themeBaseBg(palette, isDark) : cell.isContainer ? baseColor2 : fillMode === "solid" ? baseColor2 : mix(baseColor2, palette.bg, LEAF_MUTE_PCT);
72611
72904
  const drillable = cell.isContainer || cell.isCollapsed;
72612
72905
  const g = root.append("g").attr("class", "dgmo-treemap-cell").attr("transform", `translate(${cell.x0},${cell.y0})`).attr("data-node-path", cell.path.join(" / "));
72613
72906
  if (cell.lineNumber !== void 0) {
@@ -72622,16 +72915,15 @@ function renderTreemap(container, parsed, palette, isDark, exportDims, options =
72622
72915
  const rect2 = g.append("rect").attr(
72623
72916
  "class",
72624
72917
  cell.isContainer ? "dgmo-treemap-rect branch" : "dgmo-treemap-rect"
72625
- ).attr("width", w).attr("height", h).attr("rx", 2).attr("fill", fill2).attr("fill-opacity", 1).attr("stroke", palette.bg).attr("stroke-width", cell.isContainer ? 1 : 0);
72918
+ ).attr("width", w).attr("height", h).attr("rx", 2).attr("fill", fill2).attr("fill-opacity", 1).attr("stroke", fillMode === "outline" ? baseColor2 : palette.bg).attr(
72919
+ "stroke-width",
72920
+ fillMode === "outline" ? 1 : cell.isContainer ? 1 : 0
72921
+ );
72626
72922
  if (drillable && options.onClickItem && cell.lineNumber !== void 0) {
72627
72923
  const ln = cell.lineNumber;
72628
72924
  rect2.style("cursor", "pointer").on("click", () => options.onClickItem(ln));
72629
72925
  }
72630
- const ink = contrastText(
72631
- fill2,
72632
- palette.textOnFillLight,
72633
- palette.textOnFillDark
72634
- );
72926
+ const ink = fillMode === "outline" ? baseColor2 : contrastText(fill2, palette.textOnFillLight, palette.textOnFillDark);
72635
72927
  if (cell.isContainer && headerH > 0 && w > 34 && h > headerH) {
72636
72928
  const valParts = [];
72637
72929
  if (!opts.noValues) valParts.push(compactNumber2(cell.value));
@@ -73008,7 +73300,8 @@ function renderBlock(container, parsed, palette, isDark, exportDims, options = {
73008
73300
  activeGroup,
73009
73301
  activeKey: activeGroup ? tagAttrKey(activeGroup) : null,
73010
73302
  neutral,
73011
- solidFill: opts.solidFill,
73303
+ fillMode: opts.fillMode,
73304
+ isDark,
73012
73305
  onToggle: options.onToggle
73013
73306
  });
73014
73307
  if (legend) {
@@ -73046,7 +73339,7 @@ function clipLabel2(s, maxWidth, fs) {
73046
73339
  return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
73047
73340
  }
73048
73341
  function drawItems(g, items, ctx, path = []) {
73049
- const { palette, solidFill: solid } = ctx;
73342
+ const { palette, fillMode } = ctx;
73050
73343
  for (const it of items) {
73051
73344
  if (it.type === "empty") {
73052
73345
  g.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 7).attr("fill", "none").attr("stroke", ctx.neutral).attr("stroke-width", 1).attr("stroke-dasharray", "3 4").attr("opacity", 0.7);
@@ -73064,17 +73357,17 @@ function drawItems(g, items, ctx, path = []) {
73064
73357
  if (v) cell.attr(`data-tag-${ctx.activeKey}`, v);
73065
73358
  }
73066
73359
  if (it.type === "collapsed") {
73067
- const fill3 = color ? solid ? color : mix(color, palette.bg, 12) : palette.surface;
73360
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 12) : palette.surface;
73068
73361
  const cid = `dgmo-block-clip-${clipCounter++}`;
73069
73362
  cell.append("clipPath").attr("id", cid).append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10);
73070
73363
  cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
73071
73364
  cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 4).attr("text-anchor", "middle").attr("font-size", 12.5).attr("font-weight", 700).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 24, 12.5));
73072
- cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", solid && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
73365
+ cell.append("rect").attr("x", it.x).attr("y", it.y + it.h - BLOCK_BAR_H).attr("width", it.w).attr("height", BLOCK_BAR_H).attr("fill", fillMode === "solid" && color ? palette.text : stroke2).attr("clip-path", `url(#${cid})`);
73073
73366
  bindToggle(cell, it, ctx, it.h);
73074
73367
  continue;
73075
73368
  }
73076
73369
  if (it.type === "container") {
73077
- const fill3 = color ? solid ? color : mix(color, palette.bg, 7) : palette.surface;
73370
+ const fill3 = color ? fillMode === "solid" ? color : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 7) : palette.surface;
73078
73371
  cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 10).attr("fill", fill3).attr("stroke", stroke2).attr("stroke-width", 1.5);
73079
73372
  const sizeMetric = Math.min(it.w, it.h * 2.5);
73080
73373
  const headerFs = Math.max(
@@ -73089,7 +73382,7 @@ function drawItems(g, items, ctx, path = []) {
73089
73382
  if (it.inner) drawItems(g, it.inner, ctx, itemPath);
73090
73383
  continue;
73091
73384
  }
73092
- const fill2 = color ? solid ? mix(color, palette.bg, 80) : mix(color, palette.bg, 14) : palette.bg;
73385
+ const fill2 = color ? fillMode === "solid" ? mix(color, palette.bg, 80) : fillMode === "outline" ? themeBaseBg(palette, ctx.isDark) : mix(color, palette.bg, 14) : palette.bg;
73093
73386
  cell.attr("data-leaf", "true");
73094
73387
  cell.append("rect").attr("x", it.x).attr("y", it.y).attr("width", it.w).attr("height", it.h).attr("rx", 8).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
73095
73388
  cell.append("text").attr("x", it.x + it.w / 2).attr("y", it.y + it.h / 2 + 5).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 600).attr("fill", palette.text).text(clipLabel2(it.label ?? "", it.w - 16, 13));
@@ -73192,7 +73485,11 @@ function resolvePaint(parsed, palette, isDark, pctFrac) {
73192
73485
  const base = parsed.color && resolveColor(parsed.color, palette) || parsed.color || autoColor || getSeriesColors(palette)[0];
73193
73486
  return {
73194
73487
  base,
73195
- fill: shapeFill(palette, base, isDark, { solid: parsed.options.solidFill }),
73488
+ // §1.9 fill family: tint (default) / solid / outline. In outline mode the
73489
+ // progress region renders hollow (theme base bg) and the traffic-light /
73490
+ // override color moves to the border — advancement still reads from the
73491
+ // outlined region's extent against the gray track.
73492
+ fill: shapeFill(palette, base, isDark, { mode: parsed.options.fillMode }),
73196
73493
  track: mix(palette.border, themeBaseBg(palette, isDark), 45),
73197
73494
  text: palette.text,
73198
73495
  muted: mix(palette.text, themeBaseBg(palette, isDark), 55)
@@ -73322,7 +73619,7 @@ function renderBar2(svg, parsed, metrics, paint) {
73322
73619
  g.append("rect").attr("x", x).attr("y", y).attr("width", trackW).attr("height", trackH).attr("rx", r).attr("fill", paint.track);
73323
73620
  const fillW = trackW * metrics.fillFrac;
73324
73621
  if (fillW > 0.5) {
73325
- g.append("rect").attr("x", x).attr("y", y).attr("width", fillW).attr("height", trackH).attr("rx", r).attr("fill", paint.fill).attr("stroke", paint.base).attr("stroke-width", 2);
73622
+ g.append("rect").attr("x", x).attr("y", y).attr("width", fillW).attr("height", trackH).attr("rx", r).attr("fill", paint.fill).attr("stroke", paint.base).attr("stroke-width", parsed.options.fillMode === "outline" ? 1.5 : 2);
73326
73623
  }
73327
73624
  if (!parsed.options.noValue) {
73328
73625
  const valX = Math.max(x + fillW - 16, x + 52);
@@ -73367,7 +73664,7 @@ function renderThermometer(svg, parsed, metrics, paint) {
73367
73664
  const yBase = bulbCy - Math.sqrt(mBulb * mBulb - mHalf * mHalf);
73368
73665
  const yForFrac = (f) => yTop + (1 - f) * (yBase - yTop);
73369
73666
  const fillTopY = clamp5(yForFrac(metrics.fillFrac), yTop, yBase);
73370
- g.append("path").attr("d", bodyPath(fillTopY, mHalf, mBulb, false)).attr("fill", paint.fill).attr("stroke", paint.base).attr("stroke-width", 2).attr("stroke-linejoin", "round");
73667
+ g.append("path").attr("d", bodyPath(fillTopY, mHalf, mBulb, false)).attr("fill", paint.fill).attr("stroke", paint.base).attr("stroke-width", parsed.options.fillMode === "outline" ? 1.5 : 2).attr("stroke-linejoin", "round");
73371
73668
  if (parsed.hasTarget) {
73372
73669
  const edgeX = cx + r;
73373
73670
  const tickLabelX = edgeX + 14;
@@ -73451,7 +73748,13 @@ function renderGauge(svg, parsed, metrics, paint) {
73451
73748
  }
73452
73749
  g.append("path").attr("d", arcPath(cx, cy, r, 0, 1)).attr("fill", "none").attr("stroke", paint.track).attr("stroke-width", stroke2).attr("stroke-linecap", "round");
73453
73750
  if (metrics.fillFrac > 1e-3) {
73454
- g.append("path").attr("d", arcPath(cx, cy, r, 0, metrics.fillFrac)).attr("fill", "none").attr("stroke", paint.fill).attr("stroke-width", stroke2).attr("stroke-linecap", "round");
73751
+ const valueArc = arcPath(cx, cy, r, 0, metrics.fillFrac);
73752
+ if (parsed.options.fillMode === "outline") {
73753
+ g.append("path").attr("d", valueArc).attr("fill", "none").attr("stroke", paint.base).attr("stroke-width", stroke2).attr("stroke-linecap", "round");
73754
+ g.append("path").attr("d", valueArc).attr("fill", "none").attr("stroke", paint.fill).attr("stroke-width", stroke2 - 3).attr("stroke-linecap", "round");
73755
+ } else {
73756
+ g.append("path").attr("d", valueArc).attr("fill", "none").attr("stroke", paint.fill).attr("stroke-width", stroke2).attr("stroke-linecap", "round");
73757
+ }
73455
73758
  }
73456
73759
  const a = Math.PI - metrics.fillFrac * Math.PI;
73457
73760
  const needleLen = r - stroke2 / 2 - 6;
@@ -73558,7 +73861,7 @@ function stampRecur(sel, parsed) {
73558
73861
  if (r.anchorMs !== void 0) sel.attr("data-dgmo-recur-anchor", r.anchorMs);
73559
73862
  if (r.tz !== void 0) sel.attr("data-dgmo-recur-tz", r.tz);
73560
73863
  }
73561
- function bandColors(palette, accent, muted, faint) {
73864
+ function bandColors(palette, accent, muted, faint, isDark, fillMode) {
73562
73865
  const blue = resolveColor("blue", palette) ?? mix(palette.text, palette.bg, 45);
73563
73866
  const collides = accent.toLowerCase() === blue.toLowerCase();
73564
73867
  const now = collides ? resolveColor("teal", palette) ?? resolveColor("cyan", palette) ?? mix(palette.text, palette.bg, 55) : blue;
@@ -73573,7 +73876,11 @@ function bandColors(palette, accent, muted, faint) {
73573
73876
  event: accent,
73574
73877
  midSoft: mix(mid, palette.bg, 24),
73575
73878
  inert: mix(palette.text, palette.bg, 7),
73576
- inertBorder: mix(palette.text, palette.bg, 22)
73879
+ inertBorder: mix(palette.text, palette.bg, 22),
73880
+ fillMode,
73881
+ baseBg: themeBaseBg(palette, isDark),
73882
+ onLight: palette.textOnFillLight,
73883
+ onDark: palette.textOnFillDark
73577
73884
  };
73578
73885
  }
73579
73886
  function roleStyle(C, role) {
@@ -73583,15 +73890,26 @@ function roleStyle(C, role) {
73583
73890
  case "future":
73584
73891
  return { fill: C.inert, stroke: C.inertBorder, text: C.muted };
73585
73892
  case "today":
73586
- return { fill: C.now, stroke: C.now, text: C.bg };
73893
+ return chipStyle(C, C.now);
73587
73894
  case "event":
73588
- return { fill: C.event, stroke: C.event, text: C.bg };
73895
+ return chipStyle(C, C.event);
73589
73896
  }
73590
73897
  }
73898
+ function chipStyle(C, color) {
73899
+ if (C.fillMode === "outline")
73900
+ return { fill: C.baseBg, stroke: color, text: color };
73901
+ if (C.fillMode === "solid")
73902
+ return {
73903
+ fill: color,
73904
+ stroke: color,
73905
+ text: contrastText(color, C.onLight, C.onDark)
73906
+ };
73907
+ return { fill: color, stroke: color, text: C.bg };
73908
+ }
73591
73909
  function gradStyle(C, frac) {
73592
73910
  const t = Math.max(0, Math.min(1, frac));
73593
73911
  const f = mix(C.event, C.now, Math.round(t * 100));
73594
- return { fill: f, stroke: f, text: C.bg };
73912
+ return chipStyle(C, f);
73595
73913
  }
73596
73914
  function aText(svg, x, y, size, fill2, weight, anchor, txt, extra) {
73597
73915
  const t = svg.append("text").attr("x", x).attr("y", y).attr("text-anchor", anchor).attr("font-size", size).attr("font-weight", weight).attr("fill", fill2).attr("font-family", FONT_FAMILY).attr("font-variant-numeric", "tabular-nums").text(txt);
@@ -74111,13 +74429,14 @@ function vizToday(svg, g, resolvedMs, C) {
74111
74429
  }
74112
74430
  const w = Math.min(120, g.contentW * 0.16);
74113
74431
  const h = g.height * 0.52;
74114
- aRect(svg, cx - w / 2, cy - h / 2, w, h, 18, C.event, C.event, 2);
74432
+ const st = roleStyle(C, "event");
74433
+ aRect(svg, cx - w / 2, cy - h / 2, w, h, 18, st.fill, st.stroke, 2);
74115
74434
  aText(
74116
74435
  svg,
74117
74436
  cx,
74118
74437
  cy - h * 0.14,
74119
74438
  14,
74120
- C.bg,
74439
+ st.text,
74121
74440
  700,
74122
74441
  "middle",
74123
74442
  MON_ABBR[ev.getMonth()].toUpperCase(),
@@ -74128,7 +74447,7 @@ function vizToday(svg, g, resolvedMs, C) {
74128
74447
  cx,
74129
74448
  cy + h * 0.22,
74130
74449
  Math.min(48, h * 0.4),
74131
- C.bg,
74450
+ st.text,
74132
74451
  800,
74133
74452
  "middle",
74134
74453
  String(ev.getDate())
@@ -74468,7 +74787,14 @@ function renderCountdown(container, parsed, palette, isDark, exportDims) {
74468
74787
  );
74469
74788
  svg.attr("height", bannerH).attr("viewBox", `0 0 ${width} ${bannerH}`);
74470
74789
  bgRect.attr("height", bannerH);
74471
- const bandC = bandColors(palette, accent, muted, faint);
74790
+ const bandC = bandColors(
74791
+ palette,
74792
+ accent,
74793
+ muted,
74794
+ faint,
74795
+ isDark,
74796
+ parsed.fillMode
74797
+ );
74472
74798
  if (hasBand && resolved !== null) {
74473
74799
  drawBand2(
74474
74800
  svg,
@@ -74677,7 +75003,7 @@ function renderClock(container, parsed, palette, isDark, exportDims) {
74677
75003
  const rowH = 84;
74678
75004
  const svg = d3Selection36.select(container).append("svg").attr("width", width).attr("preserveAspectRatio", "xMidYMid meet").attr("xmlns", "http://www.w3.org/2000/svg").attr("role", "img").attr("aria-label", `${parsed.title ?? "Clock"} \u2014 world clocks`).style("font-family", FONT_FAMILY);
74679
75005
  const bgRect = svg.append("rect").attr("width", width).attr("fill", palette.bg);
74680
- const card = svg.append("rect").attr("x", cardM).attr("y", cardM).attr("width", width - 2 * cardM).attr("rx", 14).attr("fill", cardFill).attr("stroke", mix(palette.text, palette.bg, 40)).attr("stroke-width", 1);
75006
+ const card = svg.append("rect").attr("x", cardM).attr("y", cardM).attr("width", width - 2 * cardM).attr("rx", 14).attr("fill", parsed.fillMode === "outline" ? baseBg : cardFill).attr("stroke", mix(palette.text, palette.bg, 40)).attr("stroke-width", 1);
74681
75007
  clipSeq += 1;
74682
75008
  const clipId = `dgmo-clock-clip-${clipSeq}`;
74683
75009
  const clipRect = svg.append("clipPath").attr("id", clipId).append("rect").attr("x", cardM).attr("y", cardM).attr("width", width - 2 * cardM).attr("rx", 14);
@@ -74705,6 +75031,8 @@ function renderClock(container, parsed, palette, isDark, exportDims) {
74705
75031
  line2: line22,
74706
75032
  tick: mix(palette.text, palette.bg, 35),
74707
75033
  cardFill,
75034
+ baseBg,
75035
+ fillMode: parsed.fillMode,
74708
75036
  sw,
74709
75037
  palette
74710
75038
  };
@@ -74746,6 +75074,9 @@ function renderClock(container, parsed, palette, isDark, exportDims) {
74746
75074
  bgRect.attr("height", bannerH);
74747
75075
  card.attr("height", bannerH - 2 * cardM);
74748
75076
  }
75077
+ function zoneFillMode(entry, parsed, col) {
75078
+ return entry.color || parsed.colorBy === "place" ? col.fillMode : void 0;
75079
+ }
74749
75080
  function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
74750
75081
  const { padX } = geom;
74751
75082
  const { text, muted, line2: line22, tick, sw, cardFill } = col;
@@ -74773,9 +75104,10 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
74773
75104
  });
74774
75105
  const rightBlockW = 178;
74775
75106
  const rightColLeft = geom.rightX - rightBlockW;
75107
+ const fm = zoneFillMode(entry, parsed, col);
74776
75108
  const g = svg.append("g").attr("data-line-number", entry.lineNumber);
74777
75109
  if (auto) {
74778
- g.append("rect").attr("data-dgmo-clock-lane", "").attr("x", 9).attr("y", rowTop).attr("width", geom.width - 18).attr("height", rowH).attr("fill", auto.laneTint);
75110
+ g.append("rect").attr("data-dgmo-clock-lane", "").attr("x", 9).attr("y", rowTop).attr("width", geom.width - 18).attr("height", rowH).attr("fill", fm === "outline" ? col.baseBg : auto.laneTint);
74779
75111
  }
74780
75112
  g.attr("data-dgmo-clock", "").attr("data-dgmo-clock-zone", entry.zone).attr("data-dgmo-clock-face", parsed.face).attr("data-dgmo-clock-hours12", parsed.hours12 ? "1" : "0").attr("data-dgmo-clock-sun", sun ? "1" : "0").attr("data-dgmo-clock-c-day", sw.day).attr("data-dgmo-clock-c-night", sw.night).attr("data-dgmo-clock-c-day-soft", sw.dayTint).attr("data-dgmo-clock-c-night-soft", sw.nightTint).attr("data-dgmo-clock-c-ok", sw.ok).attr("data-dgmo-clock-c-soon", sw.soon).attr("data-dgmo-clock-c-off", sw.off).attr("data-dgmo-clock-c-ok-soft", sw.okSoft).attr("data-dgmo-clock-c-soon-soft", sw.soonSoft).attr("data-dgmo-clock-c-off-soft", sw.offSoft);
74781
75113
  if (entry.lat !== null) g.attr("data-dgmo-clock-lat", entry.lat);
@@ -74790,12 +75122,18 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
74790
75122
  }
74791
75123
  const contentLeft = padX + 4;
74792
75124
  const timeColor = auto?.solid ?? text;
74793
- const faceFill = auto ? mix(auto.solid, cardFill, 20) : stTint;
75125
+ const faceFill = auto && fm === "outline" ? col.baseBg : auto && fm === "solid" ? auto.solid : auto ? mix(auto.solid, cardFill, 20) : stTint;
74794
75126
  const ringColor = auto?.solid ?? line22;
74795
- const accentColor = auto?.solid ?? stColor;
75127
+ const handInk = auto && fm === "solid" ? contrastText(
75128
+ auto.solid,
75129
+ col.palette.textOnFillLight,
75130
+ col.palette.textOnFillDark
75131
+ ) : text;
75132
+ const accentColor = auto && fm === "solid" ? handInk : auto?.solid ?? stColor;
74796
75133
  if (auto) {
74797
75134
  g.attr("data-dgmo-clock-auto-solid", auto.solid).attr("data-dgmo-clock-auto-face", faceFill).attr("data-dgmo-clock-auto-mode", parsed.colorBy).attr("data-dgmo-clock-cardfill", cardFill);
74798
75135
  }
75136
+ if (fm) g.attr("data-dgmo-clock-fill-mode", fm);
74799
75137
  if (parsed.face === "analog") {
74800
75138
  const size = rowH - 20;
74801
75139
  const fx = contentLeft;
@@ -74808,8 +75146,8 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
74808
75146
  fg.append("line").attr("x1", 50 + 39 * Math.sin(a)).attr("y1", 50 - 39 * Math.cos(a)).attr("x2", 50 + 46 * Math.sin(a)).attr("y2", 50 - 46 * Math.cos(a)).attr("stroke", tick).attr("stroke-width", 1.8);
74809
75147
  }
74810
75148
  const ang = handAngles(parts.h, parts.m, parts.s);
74811
- fg.append("line").attr("data-dgmo-clock-hand", "h").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 28).attr("stroke", text).attr("stroke-width", 4).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.hour} 50 50)`);
74812
- fg.append("line").attr("data-dgmo-clock-hand", "m").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 17).attr("stroke", text).attr("stroke-width", 2.6).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.minute} 50 50)`);
75149
+ fg.append("line").attr("data-dgmo-clock-hand", "h").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 28).attr("stroke", handInk).attr("stroke-width", 4).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.hour} 50 50)`);
75150
+ fg.append("line").attr("data-dgmo-clock-hand", "m").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 17).attr("stroke", handInk).attr("stroke-width", 2.6).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.minute} 50 50)`);
74813
75151
  fg.append("line").attr("data-dgmo-clock-hand", "s").attr("x1", 50).attr("y1", 55).attr("x2", 50).attr("y2", 14).attr("stroke", accentColor).attr("stroke-width", 1.3).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.second} 50 50)`);
74814
75152
  fg.append("circle").attr("data-dgmo-clock-center", "").attr("cx", 50).attr("cy", 50).attr("r", 2.6).attr("fill", accentColor);
74815
75153
  } else {
@@ -74869,10 +75207,7 @@ function drawRow(svg, entry, index, parsed, now, rowTop, rowH, geom, col) {
74869
75207
  g.append("text").attr("x", textX).attr("y", yy).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", 14).attr("font-weight", 500).text(ellipsize(entry.place, 14, textMax));
74870
75208
  } else if (ln.kind === "avail" && status) {
74871
75209
  const stCol = status.cls === "ok" ? sw.ok : status.cls === "soon" ? sw.soon : sw.off;
74872
- const dot = g.append("circle").attr("data-dgmo-clock-status-dot", "").attr("cx", iconX).attr("cy", yy - 5).attr("r", 5);
74873
- if (status.cls === "off")
74874
- dot.attr("fill", "none").attr("stroke", stCol).attr("stroke-width", 1.6);
74875
- else dot.attr("fill", stCol).attr("stroke", "none");
75210
+ drawStatusClock(g, iconX, yy - 5, 5, stCol);
74876
75211
  g.append("text").attr("data-dgmo-clock-status", "").attr("x", textX).attr("y", yy).attr("fill", stCol).attr("font-family", FONT_FAMILY).attr("font-size", 14).attr("font-weight", 600).text(ellipsize(status.text, 14, textMax));
74877
75212
  } else if (ln.kind === "sun" && sun) {
74878
75213
  drawSunMoon(g, iconX, yy - 5, up, sw, 1.25);
@@ -74890,6 +75225,9 @@ function drawFixedGlyph(parent, cx, cy, color) {
74890
75225
  g.append("line").attr("x1", -4 * Math.cos(a)).attr("y1", -4 * Math.sin(a)).attr("x2", 4 * Math.cos(a)).attr("y2", 4 * Math.sin(a)).attr("stroke", color).attr("stroke-width", 1.2).attr("stroke-linecap", "round");
74891
75226
  }
74892
75227
  }
75228
+ function drawStatusClock(parent, cx, cy, r, color) {
75229
+ parent.append("circle").attr("data-dgmo-clock-status-icon", "").attr("cx", cx).attr("cy", cy).attr("r", r).attr("fill", color);
75230
+ }
74893
75231
  function bakeAnchors(g, entry, parsed, sun, sw) {
74894
75232
  g.attr("data-dgmo-clock", "").attr("data-dgmo-clock-zone", entry.zone).attr("data-dgmo-clock-face", parsed.face).attr("data-dgmo-clock-hours12", parsed.hours12 ? "1" : "0").attr("data-dgmo-clock-sun", sun ? "1" : "0").attr("data-dgmo-clock-c-day", sw.day).attr("data-dgmo-clock-c-night", sw.night).attr("data-dgmo-clock-c-day-soft", sw.dayTint).attr("data-dgmo-clock-c-night-soft", sw.nightTint).attr("data-dgmo-clock-c-ok", sw.ok).attr("data-dgmo-clock-c-soon", sw.soon).attr("data-dgmo-clock-c-off", sw.off).attr("data-dgmo-clock-c-ok-soft", sw.okSoft).attr("data-dgmo-clock-c-soon-soft", sw.soonSoft).attr("data-dgmo-clock-c-off-soft", sw.offSoft);
74895
75233
  if (entry.lat !== null) g.attr("data-dgmo-clock-lat", entry.lat);
@@ -74936,19 +75274,26 @@ function drawColumns(body, parsed, now, top, geom, col) {
74936
75274
  palette: col.palette,
74937
75275
  cardFill
74938
75276
  });
75277
+ const fm = zoneFillMode(entry, parsed, col);
74939
75278
  const timeColor = auto?.solid ?? text;
74940
- const faceFill = auto ? mix(auto.solid, cardFill, 20) : stTint;
75279
+ const faceFill = auto && fm === "outline" ? col.baseBg : auto && fm === "solid" ? auto.solid : auto ? mix(auto.solid, cardFill, 20) : stTint;
74941
75280
  const ringColor = auto?.solid ?? line22;
74942
- const accentColor = auto?.solid ?? stColor;
75281
+ const handInk = auto && fm === "solid" ? contrastText(
75282
+ auto.solid,
75283
+ col.palette.textOnFillLight,
75284
+ col.palette.textOnFillDark
75285
+ ) : text;
75286
+ const accentColor = auto && fm === "solid" ? handInk : auto?.solid ?? stColor;
74943
75287
  const g = body.append("g").attr("data-line-number", entry.lineNumber);
74944
75288
  bakeAnchors(g, entry, parsed, sun, sw);
74945
75289
  if (auto)
74946
75290
  tints.push(
74947
- g.append("rect").attr("data-dgmo-clock-lane", "").attr("x", x0).attr("y", top).attr("width", colW).attr("fill", auto.laneTint)
75291
+ g.append("rect").attr("data-dgmo-clock-lane", "").attr("x", x0).attr("y", top).attr("width", colW).attr("fill", fm === "outline" ? col.baseBg : auto.laneTint)
74948
75292
  );
74949
75293
  if (auto) {
74950
75294
  g.attr("data-dgmo-clock-auto-solid", auto.solid).attr("data-dgmo-clock-auto-face", faceFill).attr("data-dgmo-clock-auto-mode", parsed.colorBy).attr("data-dgmo-clock-cardfill", cardFill);
74951
75295
  }
75296
+ if (fm) g.attr("data-dgmo-clock-fill-mode", fm);
74952
75297
  let cy = top + (parsed.face === "analog" ? 22 : 36);
74953
75298
  const innerW = colW - 16;
74954
75299
  if (parsed.face === "analog") {
@@ -74964,8 +75309,8 @@ function drawColumns(body, parsed, now, top, geom, col) {
74964
75309
  fg.append("line").attr("x1", 50 + 39 * Math.sin(a)).attr("y1", 50 - 39 * Math.cos(a)).attr("x2", 50 + 46 * Math.sin(a)).attr("y2", 50 - 46 * Math.cos(a)).attr("stroke", tick).attr("stroke-width", 1.8);
74965
75310
  }
74966
75311
  const ang = handAngles(parts.h, parts.m, parts.s);
74967
- fg.append("line").attr("data-dgmo-clock-hand", "h").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 28).attr("stroke", text).attr("stroke-width", 4).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.hour} 50 50)`);
74968
- fg.append("line").attr("data-dgmo-clock-hand", "m").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 17).attr("stroke", text).attr("stroke-width", 2.6).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.minute} 50 50)`);
75312
+ fg.append("line").attr("data-dgmo-clock-hand", "h").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 28).attr("stroke", handInk).attr("stroke-width", 4).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.hour} 50 50)`);
75313
+ fg.append("line").attr("data-dgmo-clock-hand", "m").attr("x1", 50).attr("y1", 50).attr("x2", 50).attr("y2", 17).attr("stroke", handInk).attr("stroke-width", 2.6).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.minute} 50 50)`);
74969
75314
  fg.append("line").attr("data-dgmo-clock-hand", "s").attr("x1", 50).attr("y1", 55).attr("x2", 50).attr("y2", 14).attr("stroke", accentColor).attr("stroke-width", 1.3).attr("stroke-linecap", "round").attr("transform", `rotate(${ang.second} 50 50)`);
74970
75315
  fg.append("circle").attr("data-dgmo-clock-center", "").attr("cx", 50).attr("cy", 50).attr("r", 2.6).attr("fill", accentColor);
74971
75316
  cy += size + 6;
@@ -75025,10 +75370,7 @@ function drawColumns(body, parsed, now, top, geom, col) {
75025
75370
  g.append("text").attr("x", textX).attr("y", yy).attr("fill", muted).attr("font-family", FONT_FAMILY).attr("font-size", 12).text(ellipsize(entry.place, 12, tmax));
75026
75371
  } else if (kind === "avail" && status) {
75027
75372
  const stCol = status.cls === "ok" ? sw.ok : status.cls === "soon" ? sw.soon : sw.off;
75028
- const dot = g.append("circle").attr("data-dgmo-clock-status-dot", "").attr("cx", iconX).attr("cy", yy - 4).attr("r", 4);
75029
- if (status.cls === "off")
75030
- dot.attr("fill", "none").attr("stroke", stCol).attr("stroke-width", 1.4);
75031
- else dot.attr("fill", stCol).attr("stroke", "none");
75373
+ drawStatusClock(g, iconX, yy - 4, 4, stCol);
75032
75374
  g.append("text").attr("data-dgmo-clock-status", "").attr("x", textX).attr("y", yy).attr("fill", stCol).attr("font-family", FONT_FAMILY).attr("font-size", 12).attr("font-weight", 600).text(ellipsize(status.text, 12, tmax));
75033
75375
  } else if (kind === "sun" && sun) {
75034
75376
  drawSunMoon(g, iconX, yy - 4, up, sw, 1);
@@ -75676,7 +76018,7 @@ function clip3(s, maxW, fs) {
75676
76018
  }
75677
76019
  return lo <= 0 ? "" : s.slice(0, lo) + "\u2026";
75678
76020
  }
75679
- function paintForAccent(palette, isDark, accent) {
76021
+ function paintForAccent(palette, isDark, accent, fillMode) {
75680
76022
  const base = themeBaseBg(palette, isDark);
75681
76023
  return {
75682
76024
  accent,
@@ -75687,12 +76029,14 @@ function paintForAccent(palette, isDark, accent) {
75687
76029
  hair: mix(palette.text, base, 34),
75688
76030
  wire: mix(palette.text, base, 30),
75689
76031
  track: mix(palette.border, base, 55),
75690
- tint: shapeFill(palette, accent, isDark)
76032
+ // §1.9 fill family rides through shapeFill: solid ⇒ raw accent,
76033
+ // outline ⇒ theme base bg (accent stays on the stroke), absent ⇒ 25% tint.
76034
+ tint: shapeFill(palette, accent, isDark, { mode: fillMode })
75691
76035
  };
75692
76036
  }
75693
- function paintFor(palette, isDark, sideColor) {
76037
+ function paintFor(palette, isDark, sideColor, fillMode) {
75694
76038
  const accent = sideColor && resolveColor(sideColor, palette) || sideColor || getSeriesColors(palette)[0];
75695
- return paintForAccent(palette, isDark, accent);
76039
+ return paintForAccent(palette, isDark, accent, fillMode);
75696
76040
  }
75697
76041
  function resolveBracketLegend(parsed, palette) {
75698
76042
  const activeTag = parsed.activeTag;
@@ -75788,7 +76132,8 @@ function renderBracket(container, parsed, palette, isDark, exportDims) {
75788
76132
  });
75789
76133
  }
75790
76134
  const baseAccent = parsed.accentColor ?? resolveColor("blue", palette) ?? getSeriesColors(palette)[0];
75791
- const basePaint = paintForAccent(palette, isDark, baseAccent);
76135
+ const fillMode = parsed.fillMode;
76136
+ const basePaint = paintForAccent(palette, isDark, baseAccent, fillMode);
75792
76137
  const sideColorByLabel = /* @__PURE__ */ new Map();
75793
76138
  for (const s of parsed.sides) sideColorByLabel.set(s.label, s.color);
75794
76139
  const sideBarH = layout.sideLabels.length ? 30 : 0;
@@ -75801,11 +76146,20 @@ function renderBracket(container, parsed, palette, isDark, exportDims) {
75801
76146
  );
75802
76147
  const top = covered ? bandTop : 2;
75803
76148
  const c = resolveColor(col.color, palette) ?? col.color;
75804
- root.append("rect").attr("x", col.x - BOX_W / 2 - 10).attr("y", top).attr("width", BOX_W + 20).attr("height", Math.max(0, layout.height - top)).attr("rx", 10).attr("fill", mix(c, palette.bg, isDark ? 12 : 8));
76149
+ root.append("rect").attr("x", col.x - BOX_W / 2 - 10).attr("y", top).attr("width", BOX_W + 20).attr("height", Math.max(0, layout.height - top)).attr("rx", 10).attr(
76150
+ "fill",
76151
+ fillMode === "outline" ? themeBaseBg(palette, isDark) : mix(c, palette.bg, isDark ? 12 : 8)
76152
+ ).call((sel) => {
76153
+ if (fillMode === "outline")
76154
+ sel.attr("stroke", mix(c, palette.bg, 35)).attr("stroke-width", 1);
76155
+ });
75805
76156
  }
75806
76157
  for (const s of layout.sideLabels) {
75807
76158
  const c = s.color ? resolveColor(s.color, palette) ?? s.color : basePaint.accent;
75808
- root.append("rect").attr("x", s.x0 - 8).attr("y", 2).attr("width", s.x1 - s.x0 + 16).attr("height", 24).attr("rx", 8).attr("fill", mix(c, palette.bg, isDark ? 20 : 14)).attr("stroke", mix(c, palette.bg, 55)).attr("stroke-width", 1);
76159
+ root.append("rect").attr("x", s.x0 - 8).attr("y", 2).attr("width", s.x1 - s.x0 + 16).attr("height", 24).attr("rx", 8).attr(
76160
+ "fill",
76161
+ fillMode === "outline" ? themeBaseBg(palette, isDark) : mix(c, palette.bg, isDark ? 20 : 14)
76162
+ ).attr("stroke", fillMode === "outline" ? c : mix(c, palette.bg, 55)).attr("stroke-width", 1);
75809
76163
  root.append("text").attr("x", (s.x0 + s.x1) / 2).attr("y", 18).attr("text-anchor", "middle").attr("font-size", 13).attr("font-weight", 800).attr("letter-spacing", 0.3).attr("fill", c).text(clip3(s.label, s.x1 - s.x0, 13));
75810
76164
  }
75811
76165
  for (const col of layout.columns) {
@@ -75820,7 +76174,7 @@ function renderBracket(container, parsed, palette, isDark, exportDims) {
75820
76174
  drawConnector(root, m, m.botFrom, m.y + HALF_SPAN2, basePaint);
75821
76175
  }
75822
76176
  for (const m of layout.matches) {
75823
- const sidePaint = m.side && sideColorByLabel.get(m.side) ? paintFor(palette, isDark, sideColorByLabel.get(m.side)) : basePaint;
76177
+ const sidePaint = m.side && sideColorByLabel.get(m.side) ? paintFor(palette, isDark, sideColorByLabel.get(m.side), fillMode) : basePaint;
75824
76178
  const topSeed = seedByName.get(m.top ?? "") ?? null;
75825
76179
  const botSeed = seedByName.get(m.bot ?? "") ?? null;
75826
76180
  let homeName = m.home;
@@ -75858,7 +76212,8 @@ function renderBracket(container, parsed, palette, isDark, exportDims) {
75858
76212
  palette,
75859
76213
  isDark,
75860
76214
  m,
75861
- activeKey
76215
+ activeKey,
76216
+ fillMode
75862
76217
  );
75863
76218
  drawBox(
75864
76219
  root,
@@ -75870,7 +76225,8 @@ function renderBracket(container, parsed, palette, isDark, exportDims) {
75870
76225
  palette,
75871
76226
  isDark,
75872
76227
  m,
75873
- activeKey
76228
+ activeKey,
76229
+ fillMode
75874
76230
  );
75875
76231
  if (isUpset) drawUpset(root, m, sidePaint);
75876
76232
  if (m.commentary.length) drawCommentary(root, m, palette);
@@ -75889,10 +76245,10 @@ function drawConnector(g, m, from, toCy, paint) {
75889
76245
  const d = from.yA !== from.yB ? `M ${childEdge} ${from.yA} H ${midX} M ${childEdge} ${from.yB} H ${midX} M ${midX} ${vLo} V ${vHi} M ${midX} ${toCy} H ${parentEdge}` : `M ${childEdge} ${from.y} H ${midX} V ${toCy} H ${parentEdge}`;
75890
76246
  g.append("path").attr("d", d).attr("fill", "none").attr("stroke", paint.wire).attr("stroke-width", 1.5);
75891
76247
  }
75892
- function drawBox(g, cx, cy, name, info, sidePaint, palette, isDark, m, activeKey) {
76248
+ function drawBox(g, cx, cy, name, info, sidePaint, palette, isDark, m, activeKey, fillMode) {
75893
76249
  const x = cx - BOX_W / 2;
75894
76250
  const y = cy - BOX_H / 2;
75895
- const paint = info.tagColor ? paintForAccent(palette, isDark, info.tagColor) : sidePaint;
76251
+ const paint = info.tagColor ? paintForAccent(palette, isDark, info.tagColor, fillMode) : sidePaint;
75896
76252
  const cell = g.append("g").attr("class", "dgmo-bracket-box");
75897
76253
  if (m.lineNumber !== null) cell.attr("data-line-number", m.lineNumber);
75898
76254
  if (activeKey && info.tagValue)
@@ -75926,22 +76282,29 @@ function drawBox(g, cx, cy, name, info, sidePaint, palette, isDark, m, activeKey
75926
76282
  } else if (info.pending) {
75927
76283
  stroke2 = mix(paint.accent, paint.hair, 50);
75928
76284
  }
76285
+ const onSolid = fillMode === "solid" && (info.isChampion || info.isWinner) ? contrastText(
76286
+ paint.tint,
76287
+ palette.textOnFillLight,
76288
+ palette.textOnFillDark
76289
+ ) : null;
76290
+ if (onSolid) textColor = onSolid;
76291
+ const gutterColor = onSolid ?? paint.muted;
75929
76292
  const rect2 = cell.append("rect").attr("x", x).attr("y", y).attr("width", BOX_W).attr("height", BOX_H).attr("rx", 6).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sw);
75930
76293
  if (dash) rect2.attr("stroke-dasharray", dash);
75931
76294
  let leftPad = 11;
75932
76295
  if (info.seed !== null) {
75933
- cell.append("text").attr("x", x + 9).attr("y", cy + 4).attr("text-anchor", "start").attr("font-size", 10).attr("font-weight", 700).attr("fill", paint.muted).text(info.seed);
76296
+ cell.append("text").attr("x", x + 9).attr("y", cy + 4).attr("text-anchor", "start").attr("font-size", 10).attr("font-weight", 700).attr("fill", gutterColor).text(info.seed);
75934
76297
  leftPad = 9 + Math.max(12, measureText(String(info.seed), 10)) + 6;
75935
76298
  }
75936
76299
  let rightPad = 11;
75937
76300
  if (info.score) rightPad += 20;
75938
76301
  if (info.isHome) {
75939
- drawHome(cell, x + BOX_W - rightPad - 6, cy, paint.muted);
76302
+ drawHome(cell, x + BOX_W - rightPad - 6, cy, gutterColor);
75940
76303
  rightPad += 16;
75941
76304
  }
75942
76305
  cell.append("text").attr("x", x + leftPad).attr("y", cy + 4).attr("text-anchor", "start").attr("font-size", 12.5).attr("font-weight", weight).attr("fill", textColor).text(clip3(isTBD ? "TBD" : name, BOX_W - leftPad - rightPad, 12.5));
75943
76306
  if (info.score) {
75944
- cell.append("text").attr("x", x + BOX_W - 11).attr("y", cy + 4).attr("text-anchor", "end").attr("font-size", 12).attr("font-weight", info.isWinner ? 700 : 500).attr("fill", info.isWinner ? textColor : paint.muted).text(info.score);
76307
+ cell.append("text").attr("x", x + BOX_W - 11).attr("y", cy + 4).attr("text-anchor", "end").attr("font-size", 12).attr("font-weight", info.isWinner ? 700 : 500).attr("fill", info.isWinner ? textColor : gutterColor).text(info.score);
75945
76308
  }
75946
76309
  }
75947
76310
  function drawHome(cell, hx, cy, color) {
@@ -76089,7 +76452,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76089
76452
  if (width <= 0 || height <= 0) return;
76090
76453
  const tasksAll = [...allTasks(parsed)];
76091
76454
  if (tasksAll.length === 0 && parsed.phases.length === 0) return;
76092
- const solid = parsed.options["solid-fill"] === "on";
76455
+ const fillMode = fillModeFromOptions(parsed.options);
76093
76456
  const surfaceBg = themeBaseBg(palette, isDark);
76094
76457
  const roleCount = Math.max(1, parsed.roles.length);
76095
76458
  const idealWidth = roleCount * ROLE_COL_MAX + TASK_LABEL_MAX + 2 * H_MARGIN2;
@@ -76243,7 +76606,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76243
76606
  legendChipW,
76244
76607
  palette,
76245
76608
  surfaceBg,
76246
- solid,
76609
+ fillMode,
76247
76610
  onMarkerDragStart,
76248
76611
  sLegendChipGap,
76249
76612
  sLegendHeight,
@@ -76263,7 +76626,14 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76263
76626
  if (taskIdx < 0) return;
76264
76627
  const yTop = rowYs[i];
76265
76628
  const rh = taskRowContent.get(row.task.id)?.rowHeight ?? sRowHeight;
76266
- bandsG.append("rect").attr("class", "raci-row-band").attr("data-task-id", row.task.id).attr("x", sHMargin).attr("y", yTop + 2).attr("width", innerWidth).attr("height", rh - 4).attr("rx", 6).attr("fill", mix(autoAccent(taskIdx, palette), surfaceBg, 12));
76629
+ const bandAccent = autoAccent(taskIdx, palette);
76630
+ const band = bandsG.append("rect").attr("class", "raci-row-band").attr("data-task-id", row.task.id).attr("x", sHMargin).attr("y", yTop + 2).attr("width", innerWidth).attr("height", rh - 4).attr("rx", 6).attr(
76631
+ "fill",
76632
+ fillMode === "outline" ? surfaceBg : mix(bandAccent, surfaceBg, 12)
76633
+ );
76634
+ if (fillMode === "outline") {
76635
+ band.attr("stroke", bandAccent).attr("stroke-width", 1);
76636
+ }
76267
76637
  });
76268
76638
  }
76269
76639
  const columnsG = svg.append("g").attr("class", "raci-columns");
@@ -76271,14 +76641,21 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76271
76641
  const cx = roleX(i) + sColumnInset;
76272
76642
  const cw = roleColW - 2 * sColumnInset;
76273
76643
  const roleColor = parsed.roleColors[i] ?? autoAccent(i, palette);
76274
- const bodyFill = mix(roleColor, themeBaseBg(palette, isDark), 16);
76275
- const headerFill = mix(roleColor, themeBaseBg(palette, isDark), 30);
76644
+ const outline = fillMode === "outline";
76645
+ const bodyFill = outline ? surfaceBg : mix(roleColor, themeBaseBg(palette, isDark), 16);
76646
+ const headerFill = outline ? surfaceBg : mix(roleColor, themeBaseBg(palette, isDark), 30);
76276
76647
  const colG = columnsG.append("g").attr("class", "raci-column").attr("data-role-id", roleId);
76277
- colG.append("rect").attr("class", "raci-column-body").attr("x", cx).attr("y", headerY).attr("width", cw).attr("height", colTotalHeight).attr("rx", sColumnRadius).attr("fill", bodyFill);
76278
- colG.append("path").attr("class", "raci-column-header").attr(
76648
+ const bodyRect = colG.append("rect").attr("class", "raci-column-body").attr("x", cx).attr("y", headerY).attr("width", cw).attr("height", colTotalHeight).attr("rx", sColumnRadius).attr("fill", bodyFill);
76649
+ if (outline) {
76650
+ bodyRect.attr("stroke", roleColor).attr("stroke-width", 1);
76651
+ }
76652
+ const headerPath = colG.append("path").attr("class", "raci-column-header").attr(
76279
76653
  "d",
76280
76654
  topRoundedRectPath(cx, headerY, cw, sHeaderHeight, sColumnRadius)
76281
76655
  ).attr("fill", headerFill);
76656
+ if (outline) {
76657
+ headerPath.attr("stroke", roleColor).attr("stroke-width", 1);
76658
+ }
76282
76659
  const cxText = roleX(i) + roleColW / 2;
76283
76660
  colG.append("text").attr("class", "raci-column-label").attr("x", cxText).attr("y", headerY + sHeaderHeight / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", sRoleHeaderFont).attr("font-weight", 600).attr("fill", palette.text).text(
76284
76661
  truncateText(
@@ -76331,7 +76708,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76331
76708
  roleColW,
76332
76709
  parsed.variant,
76333
76710
  surfaceBg,
76334
- solid,
76711
+ fillMode,
76335
76712
  chartCanShowSummaries,
76336
76713
  sPhaseHeight,
76337
76714
  sPhaseFont,
@@ -76350,7 +76727,7 @@ function renderRaci(container, parsed, palette, isDark, handlers, exportDims) {
76350
76727
  roleColW,
76351
76728
  palette,
76352
76729
  surfaceBg,
76353
- solid,
76730
+ fillMode,
76354
76731
  taskDiagnostics,
76355
76732
  hasAnyDiagnostic,
76356
76733
  taskRowContent.get(row.task.id),
@@ -76413,7 +76790,7 @@ function setupColumnHover(svg) {
76413
76790
  svg.on("mouseover", (event) => set(findRole(event.target)));
76414
76791
  svg.on("mouseleave", () => set(null));
76415
76792
  }
76416
- function renderLegend4(svg, markers, variant, x, y, mode, chipW, palette, surfaceBg, solid, _onMarkerDragStart, sLegendChipGap, sLegendHeight, sNodeRadius, sNodeStrokeWidth, sLegendLetterFont, sLegendLabelFont) {
76793
+ function renderLegend4(svg, markers, variant, x, y, mode, chipW, palette, surfaceBg, fillMode, _onMarkerDragStart, sLegendChipGap, sLegendHeight, sNodeRadius, sNodeStrokeWidth, sLegendLetterFont, sLegendLabelFont) {
76417
76794
  if (markers.length === 0) return;
76418
76795
  const labels = MARKER_LABELS[variant];
76419
76796
  const legendG = svg.append("g").attr("class", "raci-legend").attr("aria-label", `${variant.toUpperCase()} marker legend`);
@@ -76423,12 +76800,12 @@ function renderLegend4(svg, markers, variant, x, y, mode, chipW, palette, surfac
76423
76800
  const labelText = labels[marker];
76424
76801
  const chipG = legendG.append("g").attr("class", "raci-legend-chip").attr("data-marker", marker).style("cursor", "grab");
76425
76802
  if (mode === "letters") {
76426
- const fill3 = solid ? rawColor : mix(rawColor, surfaceBg, TINT_PCT);
76427
- const stroke3 = solid ? mix(rawColor, surfaceBg, 70) : rawColor;
76803
+ const fill3 = fillMode === "solid" ? rawColor : fillMode === "outline" ? surfaceBg : mix(rawColor, surfaceBg, TINT_PCT);
76804
+ const stroke3 = fillMode === "solid" ? mix(rawColor, surfaceBg, 70) : rawColor;
76428
76805
  chipG.append("rect").attr("x", cx).attr("y", y).attr("width", chipW).attr("height", sLegendHeight).attr("rx", sNodeRadius).attr("fill", fill3).attr("stroke", stroke3).attr("stroke-width", sNodeStrokeWidth);
76429
76806
  chipG.append("text").attr("x", cx + chipW / 2).attr("y", y + sLegendHeight / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", sLegendLetterFont).attr("font-weight", 700).attr(
76430
76807
  "fill",
76431
- solid ? contrastText(
76808
+ fillMode === "solid" ? contrastText(
76432
76809
  fill3,
76433
76810
  palette.textOnFillLight,
76434
76811
  palette.textOnFillDark
@@ -76436,16 +76813,32 @@ function renderLegend4(svg, markers, variant, x, y, mode, chipW, palette, surfac
76436
76813
  ).text(marker);
76437
76814
  return;
76438
76815
  }
76439
- const fill2 = solid ? rawColor : mix(rawColor, surfaceBg, TINT_PCT);
76440
- const stroke2 = mix(rawColor, surfaceBg, 70);
76816
+ let fill2;
76817
+ if (fillMode === "outline") {
76818
+ const gradId = `raci-legend-grad-${marker}`;
76819
+ let defs = svg.select("defs");
76820
+ if (defs.empty()) defs = svg.append("defs");
76821
+ if (defs.select(`#${gradId}`).empty()) {
76822
+ const grad = defs.append("linearGradient").attr("id", gradId).attr("x1", "0%").attr("y1", "0%").attr("x2", "0%").attr("y2", "100%");
76823
+ grad.append("stop").attr("offset", "0%").attr("stop-color", mix(rawColor, surfaceBg, 38));
76824
+ grad.append("stop").attr("offset", "100%").attr("stop-color", mix(rawColor, surfaceBg, 8));
76825
+ }
76826
+ fill2 = `url(#${gradId})`;
76827
+ } else {
76828
+ fill2 = fillMode === "solid" ? rawColor : mix(rawColor, surfaceBg, TINT_PCT);
76829
+ }
76830
+ const stroke2 = fillMode === "outline" ? rawColor : mix(rawColor, surfaceBg, 70);
76441
76831
  chipG.append("rect").attr("x", cx).attr("y", y).attr("width", chipW).attr("height", sLegendHeight).attr("rx", sNodeRadius).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", sNodeStrokeWidth);
76442
76832
  const slabPad = 4;
76443
76833
  const slabW = 24;
76444
- const slabFill = solid ? mix(rawColor, surfaceBg, 70) : mix(rawColor, surfaceBg, 55);
76445
- chipG.append("rect").attr("x", cx + slabPad).attr("y", y + slabPad).attr("width", slabW).attr("height", sLegendHeight - 2 * slabPad).attr("rx", 4).attr("fill", slabFill);
76834
+ const slabFill = fillMode === "solid" ? mix(rawColor, surfaceBg, 70) : fillMode === "outline" ? surfaceBg : mix(rawColor, surfaceBg, 55);
76835
+ const slabRect = chipG.append("rect").attr("x", cx + slabPad).attr("y", y + slabPad).attr("width", slabW).attr("height", sLegendHeight - 2 * slabPad).attr("rx", 4).attr("fill", slabFill);
76836
+ if (fillMode === "outline") {
76837
+ slabRect.attr("stroke", rawColor).attr("stroke-width", 1);
76838
+ }
76446
76839
  chipG.append("text").attr("x", cx + slabPad + slabW / 2).attr("y", y + sLegendHeight / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", sLegendLetterFont).attr("font-weight", 700).attr(
76447
76840
  "fill",
76448
- solid ? contrastText(
76841
+ fillMode === "solid" ? contrastText(
76449
76842
  slabFill,
76450
76843
  palette.textOnFillLight,
76451
76844
  palette.textOnFillDark
@@ -76463,10 +76856,16 @@ function renderLegend4(svg, markers, variant, x, y, mode, chipW, palette, surfac
76463
76856
  function renderRaciForExport(container, parsed, palette, isDark, exportDims) {
76464
76857
  renderRaci(container, parsed, palette, isDark, {}, exportDims);
76465
76858
  }
76466
- function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor, roles, roleX, roleColW, variant, surfaceBg, solid, showSummary, sPhaseHeight, sPhaseFont, sColumnInset, sNodeRadius) {
76859
+ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor, roles, roleX, roleColW, variant, surfaceBg, fillMode, showSummary, sPhaseHeight, sPhaseFont, sColumnInset, sNodeRadius) {
76467
76860
  const phaseG = svg.append("g").attr("class", "raci-phase").attr("data-section", `phase-${phase.id}`).attr("data-section-toggle", "").attr("data-line-number", String(phase.lineNumber)).attr("data-phase-id", phase.id).attr("data-collapsed", collapsed ? "1" : "0").style("cursor", "pointer");
76468
- const phaseFill = mix(phase.color ?? autoColor, palette.bg, 30);
76469
- phaseG.append("rect").attr("x", x).attr("y", y + 4).attr("width", width).attr("height", sPhaseHeight - 8).attr("fill", phaseFill).attr("rx", 4);
76861
+ const phaseColor = phase.color ?? autoColor;
76862
+ const phaseRect = phaseG.append("rect").attr("x", x).attr("y", y + 4).attr("width", width).attr("height", sPhaseHeight - 8).attr(
76863
+ "fill",
76864
+ fillMode === "outline" ? surfaceBg : mix(phaseColor, palette.bg, 30)
76865
+ ).attr("rx", 4);
76866
+ if (fillMode === "outline") {
76867
+ phaseRect.attr("stroke", phaseColor).attr("stroke-width", 1.25);
76868
+ }
76470
76869
  const chevX = x + 12;
76471
76870
  const chevY = y + sPhaseHeight / 2;
76472
76871
  phaseG.append("text").attr("x", chevX).attr("y", chevY).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-family", FONT_FAMILY).attr("font-size", 9).attr("fill", palette.text).attr("opacity", 0.6).text(collapsed ? "\u25B6" : "\u25BC");
@@ -76499,13 +76898,13 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
76499
76898
  ordered.forEach((marker, i) => {
76500
76899
  const cx = startX + i * (sliceW + SLICE_GAP);
76501
76900
  const rawColor = markerColor(marker, palette);
76502
- const fill2 = solid ? rawColor : mix(rawColor, surfaceBg, TINT_PCT);
76503
- const stroke2 = solid ? mix(rawColor, surfaceBg, 70) : rawColor;
76901
+ const fill2 = fillMode === "solid" ? rawColor : fillMode === "outline" ? surfaceBg : mix(rawColor, surfaceBg, TINT_PCT);
76902
+ const stroke2 = fillMode === "solid" ? mix(rawColor, surfaceBg, 70) : rawColor;
76504
76903
  const chipG = phaseG.append("g").attr("class", "raci-phase-summary");
76505
76904
  chipG.append("rect").attr("x", cx).attr("y", summaryY).attr("width", sliceW).attr("height", SUMMARY_CHIP_H).attr("rx", sNodeRadius).attr("fill", fill2).attr("stroke", stroke2).attr("stroke-width", 1.25);
76506
76905
  chipG.append("text").attr("x", cx + sliceW / 2).attr("y", summaryY + SUMMARY_CHIP_H / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", SUMMARY_LETTER_FONT).attr("font-weight", 700).attr(
76507
76906
  "fill",
76508
- solid ? contrastText(
76907
+ fillMode === "solid" ? contrastText(
76509
76908
  fill2,
76510
76909
  palette.textOnFillLight,
76511
76910
  palette.textOnFillDark
@@ -76515,7 +76914,7 @@ function renderPhaseBar(svg, phase, x, y, width, palette, collapsed, autoColor,
76515
76914
  });
76516
76915
  }
76517
76916
  }
76518
- function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, solid, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart, sLabelFont, sDescFont, sCellPad, sRowHeight, sColumnInset, sNodeRadius, sNodeStrokeWidth, sMarkerFont, sLegendLabelFont, sStackTopGap, sViolationLineHeight) {
76917
+ function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette, surfaceBg, fillMode, taskDiagnostics, _hasAnyDiagnostic, rowContent, onClickLine, _onMarkerDragStart, sLabelFont, sDescFont, sCellPad, sRowHeight, sColumnInset, sNodeRadius, sNodeStrokeWidth, sMarkerFont, sLegendLabelFont, sStackTopGap, sViolationLineHeight) {
76519
76918
  const rowG = svg.append("g").attr("class", "raci-task-row").attr("data-task-id", task.id).attr("data-line-number", String(task.lineNumber));
76520
76919
  const labelX = x + 8;
76521
76920
  const labelMaxW = labelW - 16;
@@ -76594,7 +76993,7 @@ function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette
76594
76993
  const variantLabels = MARKER_LABELS[parsed.variant];
76595
76994
  markers.forEach((m, i) => {
76596
76995
  const rawColor = markerColor(m, palette);
76597
- const fill2 = solid ? rawColor : mix(rawColor, surfaceBg, TINT_PCT);
76996
+ const fill2 = fillMode === "solid" ? rawColor : fillMode === "outline" ? surfaceBg : mix(rawColor, surfaceBg, TINT_PCT);
76598
76997
  const stroke2 = rawColor;
76599
76998
  const sliceX = cx + i * (sliceW + SLICE_GAP);
76600
76999
  const sliceG = cellG.append("g").attr("class", "raci-marker-slice").attr("data-marker", m).style("cursor", "grab");
@@ -76606,7 +77005,7 @@ function renderTaskRow(svg, task, parsed, x, y, labelW, roleX, roleColW, palette
76606
77005
  const textFont = showFullLabel ? sLegendLabelFont : sMarkerFont;
76607
77006
  sliceG.append("text").attr("x", sliceX + sliceW / 2).attr("y", cy + ch / 2).attr("text-anchor", "middle").attr("dominant-baseline", "central").attr("font-size", textFont).attr("font-weight", MARKER_FONT_WEIGHT).attr(
76608
77007
  "fill",
76609
- solid ? contrastText(
77008
+ fillMode === "solid" ? contrastText(
76610
77009
  fill2,
76611
77010
  palette.textOnFillLight,
76612
77011
  palette.textOnFillDark
@@ -76673,6 +77072,7 @@ var MARKER_LABELS, TITLE_AREA_HEIGHT4, H_MARGIN2, V_MARGIN3, LEGEND_HEIGHT2, LEG
76673
77072
  var init_renderer32 = __esm({
76674
77073
  "src/raci/renderer.ts"() {
76675
77074
  "use strict";
77075
+ init_parsing();
76676
77076
  init_fonts();
76677
77077
  init_title_constants();
76678
77078
  init_color_utils();
@@ -76984,8 +77384,8 @@ function wrapLabelWords(words, maxWidth, fontSize) {
76984
77384
  if (current) lines.push(current);
76985
77385
  return lines;
76986
77386
  }
76987
- function renderRectParticipant(g, palette, isDark, color, solid, w = W, h = H) {
76988
- g.append("rect").attr("x", -w / 2).attr("y", 0).attr("width", w).attr("height", h).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, solid)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
77387
+ function renderRectParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
77388
+ g.append("rect").attr("x", -w / 2).attr("y", 0).attr("width", w).attr("height", h).attr("rx", 2).attr("ry", 2).attr("fill", fill(palette, isDark, color, fillMode)).attr("stroke", stroke(palette, color)).attr("stroke-width", SW);
76989
77389
  }
76990
77390
  function renderActorParticipant(g, palette, color, h = H) {
76991
77391
  const sc = h / H;
@@ -77006,11 +77406,11 @@ function renderActorParticipant(g, palette, color, h = H) {
77006
77406
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx - legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
77007
77407
  g.append("line").attr("x1", cx).attr("y1", bodyBottomY).attr("x2", cx + legSpan).attr("y2", legY).attr("stroke", s).attr("stroke-width", actorSW);
77008
77408
  }
77009
- function renderDatabaseParticipant(g, palette, isDark, color, solid, w = W, h = H) {
77409
+ function renderDatabaseParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
77010
77410
  const ry = 7;
77011
77411
  const topY = ry;
77012
77412
  const bodyH = h - ry * 2;
77013
- const f = fill(palette, isDark, color, solid);
77413
+ const f = fill(palette, isDark, color, fillMode);
77014
77414
  const s = stroke(palette, color);
77015
77415
  g.append("ellipse").attr("cx", 0).attr("cy", topY + bodyH).attr("rx", w / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
77016
77416
  g.append("rect").attr("class", "participant-body").attr("x", -w / 2).attr("y", topY).attr("width", w).attr("height", bodyH).attr("fill", f).attr("stroke", "none");
@@ -77018,11 +77418,11 @@ function renderDatabaseParticipant(g, palette, isDark, color, solid, w = W, h =
77018
77418
  g.append("line").attr("x1", w / 2).attr("y1", topY).attr("x2", w / 2).attr("y2", topY + bodyH).attr("stroke", s).attr("stroke-width", SW);
77019
77419
  g.append("ellipse").attr("cx", 0).attr("cy", topY).attr("rx", w / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
77020
77420
  }
77021
- function renderQueueParticipant(g, palette, isDark, color, solid, w = W, h = H) {
77421
+ function renderQueueParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
77022
77422
  const rx = 10;
77023
77423
  const leftX = -w / 2 + rx;
77024
77424
  const bodyW = w - rx * 2;
77025
- const f = fill(palette, isDark, color, solid);
77425
+ const f = fill(palette, isDark, color, fillMode);
77026
77426
  const s = stroke(palette, color);
77027
77427
  g.append("ellipse").attr("cx", leftX + bodyW).attr("cy", h / 2).attr("rx", rx).attr("ry", h / 2).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
77028
77428
  g.append("rect").attr("class", "participant-body").attr("x", leftX).attr("y", 0).attr("width", bodyW).attr("height", h).attr("fill", f).attr("stroke", "none");
@@ -77030,11 +77430,11 @@ function renderQueueParticipant(g, palette, isDark, color, solid, w = W, h = H)
77030
77430
  g.append("line").attr("x1", leftX).attr("y1", h).attr("x2", leftX + bodyW).attr("y2", h).attr("stroke", s).attr("stroke-width", SW);
77031
77431
  g.append("ellipse").attr("cx", leftX).attr("cy", h / 2).attr("rx", rx).attr("ry", h / 2).attr("fill", f).attr("stroke", s).attr("stroke-width", SW);
77032
77432
  }
77033
- function renderCacheParticipant(g, palette, isDark, color, solid, w = W, h = H) {
77433
+ function renderCacheParticipant(g, palette, isDark, color, fillMode, w = W, h = H) {
77034
77434
  const ry = 7;
77035
77435
  const topY = ry;
77036
77436
  const bodyH = h - ry * 2;
77037
- const f = fill(palette, isDark, color, solid);
77437
+ const f = fill(palette, isDark, color, fillMode);
77038
77438
  const s = stroke(palette, color);
77039
77439
  const dash = "4 3";
77040
77440
  g.append("ellipse").attr("cx", 0).attr("cy", topY + bodyH).attr("rx", w / 2).attr("ry", ry).attr("fill", f).attr("stroke", s).attr("stroke-width", SW).attr("stroke-dasharray", dash);
@@ -77277,7 +77677,7 @@ function applyGroupOrdering(participants, groups, messages = []) {
77277
77677
  function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateToLine, options) {
77278
77678
  d3Selection39.select(container).selectAll("*").remove();
77279
77679
  const { title, options: parsedOptions } = parsed;
77280
- const solid = parsedOptions["solid-fill"] === "on";
77680
+ const fillMode = fillModeFromOptions(parsedOptions);
77281
77681
  const effectiveCollapsedGroups = options?.collapsedGroups ? new Set(options.collapsedGroups) : new Set(
77282
77682
  parsed.groups.filter((g) => g.collapsed).map((g) => g.lineNumber)
77283
77683
  );
@@ -77837,7 +78237,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
77837
78237
  }
77838
78238
  let rightMargin = Math.max(rightProjection + 10, sGap / 2);
77839
78239
  let leftMargin = sGap / 2;
77840
- const diagramWidth = participants.length * sGap;
78240
+ const diagramWidth = Math.max(0, participants.length - 1) * sGap;
77841
78241
  let totalWidth = Math.max(
77842
78242
  leftMargin + diagramWidth + rightMargin,
77843
78243
  sBoxW + 40
@@ -78018,7 +78418,7 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
78018
78418
  isDark,
78019
78419
  effectiveTagColor,
78020
78420
  pTagAttr,
78021
- solid,
78421
+ fillMode,
78022
78422
  sBoxW,
78023
78423
  sBoxH,
78024
78424
  sLabelTextWidth,
@@ -78242,7 +78642,9 @@ function renderSequenceDiagram(container, parsed, palette, isDark, _onNavigateTo
78242
78642
  const actTagColor = getTagColor(actTagValue);
78243
78643
  const actBaseColor = actTagColor || palette.primary;
78244
78644
  svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", themeBaseBg(palette, isDark));
78245
- const actFill = shapeFill(palette, actBaseColor, isDark, { solid });
78645
+ const actFill = shapeFill(palette, actBaseColor, isDark, {
78646
+ mode: fillMode
78647
+ });
78246
78648
  const actRect = svg.append("rect").attr("x", x).attr("y", y1).attr("width", sActivationWidth).attr("height", y2 - y1).attr("fill", actFill).attr("stroke", actBaseColor).attr("stroke-width", 1).attr("stroke-opacity", 0.5).attr("data-participant-id", act.participantId).attr("data-msg-lines", coveredLines.join(",")).attr("data-line-number", coveredLines[0] ?? "").attr("class", "activation");
78247
78649
  if (tagKey && actTagValue) {
78248
78650
  actRect.attr(`data-tag-${tagKey}`, actTagValue.toLowerCase());
@@ -78480,7 +78882,7 @@ function buildNoteMessageMap(elements) {
78480
78882
  walk(elements);
78481
78883
  return map;
78482
78884
  }
78483
- function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, solid, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
78885
+ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tagAttr, fillMode, boxW = W, boxH = H, labelTextW = labelTextWidth(W), labelFontSize2 = LABEL_FONT_SIZE5) {
78484
78886
  const g = svg.append("g").attr("transform", `translate(${cx}, ${cy})`).attr("class", "participant").attr("data-participant-id", participant.id);
78485
78887
  if (tagAttr) {
78486
78888
  g.attr(`data-tag-${tagAttr.key}`, tagAttr.value);
@@ -78490,16 +78892,24 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
78490
78892
  renderActorParticipant(g, palette, color, boxH);
78491
78893
  break;
78492
78894
  case "database":
78493
- renderDatabaseParticipant(g, palette, isDark, color, solid, boxW, boxH);
78895
+ renderDatabaseParticipant(
78896
+ g,
78897
+ palette,
78898
+ isDark,
78899
+ color,
78900
+ fillMode,
78901
+ boxW,
78902
+ boxH
78903
+ );
78494
78904
  break;
78495
78905
  case "queue":
78496
- renderQueueParticipant(g, palette, isDark, color, solid, boxW, boxH);
78906
+ renderQueueParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
78497
78907
  break;
78498
78908
  case "cache":
78499
- renderCacheParticipant(g, palette, isDark, color, solid, boxW, boxH);
78909
+ renderCacheParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
78500
78910
  break;
78501
78911
  default:
78502
- renderRectParticipant(g, palette, isDark, color, solid, boxW, boxH);
78912
+ renderRectParticipant(g, palette, isDark, color, fillMode, boxW, boxH);
78503
78913
  break;
78504
78914
  }
78505
78915
  const isActor = participant.type === "actor";
@@ -78511,7 +78921,7 @@ function renderParticipant(svg, participant, cx, cy, palette, isDark, color, tag
78511
78921
  const fontSize = labelFontSize2;
78512
78922
  const lineHeight = fontSize + 2;
78513
78923
  const labelFill = isActor ? palette.text : contrastText(
78514
- fill(palette, isDark, color, solid),
78924
+ fill(palette, isDark, color, fillMode),
78515
78925
  palette.textOnFillLight,
78516
78926
  palette.textOnFillDark
78517
78927
  );
@@ -78533,6 +78943,7 @@ var init_renderer33 = __esm({
78533
78943
  "src/sequence/renderer.ts"() {
78534
78944
  "use strict";
78535
78945
  init_tag_groups();
78946
+ init_parsing();
78536
78947
  init_color_utils();
78537
78948
  init_inline_markdown();
78538
78949
  init_fonts();
@@ -78568,9 +78979,7 @@ var init_renderer33 = __esm({
78568
78979
  SELF_CALL_WIDTH = 30;
78569
78980
  ACTOR_LABEL_CLEARANCE = 22;
78570
78981
  labelTextWidth = (boxW) => boxW - 10;
78571
- fill = (palette, isDark, color, solid) => color ? shapeFill(palette, color, isDark, {
78572
- ...solid !== void 0 && { solid }
78573
- }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
78982
+ fill = (palette, isDark, color, fillMode) => color ? shapeFill(palette, color, isDark, { mode: fillMode }) : isDark ? mix(palette.overlay, palette.surface, 50) : mix(palette.bg, palette.surface, 50);
78574
78983
  stroke = (palette, color) => color || palette.border;
78575
78984
  SW = 1.5;
78576
78985
  W = PARTICIPANT_BOX_WIDTH;
@@ -79239,6 +79648,7 @@ init_parser2();
79239
79648
  // src/arc/renderer.ts
79240
79649
  init_scaling();
79241
79650
  init_d3_helpers();
79651
+ init_color_utils();
79242
79652
  import * as d3Scale2 from "d3-scale";
79243
79653
  import * as d3Selection2 from "d3-selection";
79244
79654
  import * as d3Array2 from "d3-array";
@@ -79348,8 +79758,10 @@ var ARC_NODE_LABEL_Y_OFFSET = 20;
79348
79758
  var ARC_STROKE_MIN = 1.5;
79349
79759
  var ARC_STROKE_MAX = 6;
79350
79760
  var ARC_BASELINE_STROKE_WIDTH = 1;
79351
- function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, exportDims) {
79761
+ function renderArcDiagram(container, parsed, palette, isDark, onClickItem, exportDims) {
79352
79762
  const { links, orientation, arcOrder, arcNodeGroups } = parsed;
79763
+ const outlineDots = parsed.fillMode === "outline";
79764
+ const hollowFill = themeBaseBg(palette, isDark);
79353
79765
  const title = parsed.noTitle ? null : parsed.title;
79354
79766
  if (links.length === 0) return;
79355
79767
  const init = initD3Chart(container, palette, exportDims);
@@ -79506,7 +79918,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
79506
79918
  const minY = Math.min(...positions) - bandPad;
79507
79919
  const maxY = Math.max(...positions) + bandPad;
79508
79920
  const midYBand = (minY + maxY) / 2;
79509
- g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", bandLeft).attr("y", minY).attr("width", bandRight - bandLeft).attr("height", maxY - minY).attr("rx", sBandRadius).attr("fill", group.color ?? textColor).attr("fill-opacity", group.color ? 0.15 : 0.06).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
79921
+ g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", bandLeft).attr("y", minY).attr("width", bandRight - bandLeft).attr("height", maxY - minY).attr("rx", sBandRadius).attr("fill", outlineDots ? "none" : group.color ?? textColor).attr("fill-opacity", group.color ? 0.15 : 0.06).call((sel) => {
79922
+ if (outlineDots)
79923
+ sel.attr("stroke", group.color ?? textColor).attr("stroke-width", 1.25);
79924
+ }).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
79510
79925
  if (onClickItem) onClickItem(group.lineNumber);
79511
79926
  });
79512
79927
  const nameX = bandLeft + vNameColW / 2;
@@ -79540,7 +79955,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
79540
79955
  if (onClickItem && nodeLink?.lineNumber)
79541
79956
  onClickItem(nodeLink.lineNumber);
79542
79957
  });
79543
- nodeG.append("circle").attr("cx", baseX).attr("cy", y).attr("r", sNodeRadius).attr("fill", nodeColor2).attr("stroke", bgColor).attr("stroke-width", sNodeStrokeWidth);
79958
+ nodeG.append("circle").attr("cx", baseX).attr("cy", y).attr("r", sNodeRadius).attr("fill", outlineDots ? hollowFill : nodeColor2).attr("stroke", outlineDots ? nodeColor2 : bgColor).attr(
79959
+ "stroke-width",
79960
+ outlineDots ? ctx.structural(2) : sNodeStrokeWidth
79961
+ );
79544
79962
  nodeG.append("text").attr("x", baseX - sNodeLabelXOffset).attr("y", y).attr("dy", "0.35em").attr("text-anchor", "end").attr("fill", textColor).attr("font-size", `${sNodeLabelFont}px`).text(node);
79545
79963
  }
79546
79964
  } else {
@@ -79620,7 +80038,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
79620
80038
  const bandFill = group.color ?? textColor;
79621
80039
  const bandFillOpacity = group.color ? 0.15 : 0.06;
79622
80040
  const nameY = baseY + nodeLabelDepth + sGroupLabelFont;
79623
- g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", bandLeft).attr("y", bandTopY).attr("width", bandRight - bandLeft).attr("height", bandBottomY - bandTopY).attr("rx", sBandRadius).attr("fill", bandFill).attr("fill-opacity", bandFillOpacity).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
80041
+ g.append("rect").attr("class", "arc-group-band").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", bandLeft).attr("y", bandTopY).attr("width", bandRight - bandLeft).attr("height", bandBottomY - bandTopY).attr("rx", sBandRadius).attr("fill", outlineDots ? "none" : bandFill).attr("fill-opacity", bandFillOpacity).call((sel) => {
80042
+ if (outlineDots)
80043
+ sel.attr("stroke", bandFill).attr("stroke-width", 1.25);
80044
+ }).style("cursor", "pointer").on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
79624
80045
  if (onClickItem) onClickItem(group.lineNumber);
79625
80046
  });
79626
80047
  g.append("text").attr("class", "arc-group-label").attr("data-group", group.name).attr("data-line-number", String(group.lineNumber)).attr("x", (minP + maxP) / 2).attr("y", nameY).attr("text-anchor", "middle").attr("fill", textColor).attr("font-size", `${sGroupLabelFont}px`).attr("font-weight", "600").attr("fill-opacity", 0.6).style("cursor", onClickItem ? "pointer" : "default").text(group.name).on("mouseenter", () => handleGroupEnter(group.name)).on("mouseleave", handleMouseLeave).on("click", () => {
@@ -79653,7 +80074,10 @@ function renderArcDiagram(container, parsed, palette, _isDark, onClickItem, expo
79653
80074
  if (onClickItem && nodeLink?.lineNumber)
79654
80075
  onClickItem(nodeLink.lineNumber);
79655
80076
  });
79656
- nodeG.append("circle").attr("cx", x).attr("cy", baseY).attr("r", sNodeRadius).attr("fill", nodeColor2).attr("stroke", bgColor).attr("stroke-width", sNodeStrokeWidth);
80077
+ nodeG.append("circle").attr("cx", x).attr("cy", baseY).attr("r", sNodeRadius).attr("fill", outlineDots ? hollowFill : nodeColor2).attr("stroke", outlineDots ? nodeColor2 : bgColor).attr(
80078
+ "stroke-width",
80079
+ outlineDots ? ctx.structural(2) : sNodeStrokeWidth
80080
+ );
79657
80081
  const labelY = rotateLabels ? baseY + labelPivotGap : baseY + sNodeLabelYOffset;
79658
80082
  const nodeLabel = nodeG.append("text").attr("x", x).attr("y", labelY).attr("text-anchor", rotateLabels ? "end" : "middle").attr("fill", textColor).attr("font-size", `${sNodeLabelFont}px`).text(node);
79659
80083
  if (rotateLabels) {
@@ -79868,7 +80292,7 @@ function regionCentroid(circles, inside) {
79868
80292
  }
79869
80293
  function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims) {
79870
80294
  const { vennSets, vennOverlaps } = parsed;
79871
- const solid = parsed.solidFill === true;
80295
+ const fillMode = parsed.fillMode;
79872
80296
  const title = parsed.noTitle ? null : parsed.title;
79873
80297
  if (vennSets.length < 2 || vennSets.length > 3) return;
79874
80298
  const init = initD3Chart(container, palette, exportDims);
@@ -80022,7 +80446,10 @@ function renderVenn(container, parsed, palette, _isDark, onClickItem, exportDims
80022
80446
  const circleEls = [];
80023
80447
  const circleGroup = svg.append("g");
80024
80448
  circles.forEach((c, i) => {
80025
- const el = circleGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", setColors[i]).attr("fill-opacity", solid ? 0.6 : 0.35).attr("stroke", setColors[i]).attr("stroke-width", ctx.structural(2)).style("pointer-events", "none");
80449
+ const el = circleGroup.append("circle").attr("cx", c.x).attr("cy", c.y).attr("r", c.r).attr("fill", setColors[i]).attr(
80450
+ "fill-opacity",
80451
+ fillMode === "solid" ? 0.6 : fillMode === "outline" ? 0 : 0.35
80452
+ ).attr("stroke", setColors[i]).attr("stroke-width", ctx.structural(2)).style("pointer-events", "none");
80026
80453
  circleEls.push(el);
80027
80454
  });
80028
80455
  const defs = svg.append("defs");
@@ -80748,7 +81175,7 @@ function renderQuadrant(container, parsed, palette, isDark, onClickItem, exportD
80748
81175
  if (placed.connectorLine) {
80749
81176
  pointG.append("line").attr("x1", placed.connectorLine.x1).attr("y1", placed.connectorLine.y1).attr("x2", placed.connectorLine.x2).attr("y2", placed.connectorLine.y2).attr("stroke", pointColor).attr("stroke-width", 1).attr("opacity", 0.5);
80750
81177
  }
80751
- pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", POINT_RADIUS).attr("fill", "#ffffff").attr("stroke", pointColor).attr("stroke-width", ctx.structural(2));
81178
+ pointG.append("circle").attr("cx", cx).attr("cy", cy).attr("r", POINT_RADIUS).attr("fill", parsed.fillMode === "outline" ? bg : "#ffffff").attr("stroke", pointColor).attr("stroke-width", ctx.structural(2));
80752
81179
  const labelText = pointG.append("text").attr("x", placed.x).attr("y", placed.y).attr("text-anchor", placed.anchor).attr("dominant-baseline", "central").attr("fill", textColor).attr("font-size", `${POINT_LABEL_FONT_SIZE}px`).attr("font-weight", "700").style("text-shadow", `0 1px 2px ${shadowColor}`).style("transition", "y 120ms ease-out");
80753
81180
  labelText.append("tspan").text(point.label);
80754
81181
  const coordsTspan = labelText.append("tspan").attr("class", "point-coords").attr("x", placed.x).attr("dy", `${POINT_LABEL_FONT_SIZE}px`).attr("font-size", `${ctx.text(10)}px`).attr("font-weight", "500").attr("opacity", 0).text(`${point.x.toFixed(2)}, ${point.y.toFixed(2)}`);
@@ -80854,6 +81281,9 @@ function resolveArcChordOverride(content, detectedType, palette) {
80854
81281
  if (!p.error && p.layout === "chord" && p.links.length) {
80855
81282
  const emitted = [
80856
81283
  `chord ${p.title ?? ""}`.trimEnd(),
81284
+ // §1.9 fill family survives the layout re-emit so the circular
81285
+ // renderer honors fill-solid / fill-outline authored on the arc.
81286
+ ...p.fillMode ? [`fill-${p.fillMode}`] : [],
80857
81287
  ...p.links.map((l) => `${l.source} -> ${l.target} ${l.value}`)
80858
81288
  ].join("\n");
80859
81289
  return { content: emitted, type: "chord" };
@@ -82844,20 +83274,23 @@ function updateRow(group, now) {
82844
83274
  setHand(group, "s", ang.second);
82845
83275
  const mode = group.getAttribute("data-dgmo-clock-auto-mode");
82846
83276
  const cardFill = group.getAttribute("data-dgmo-clock-cardfill");
83277
+ const fillMode = group.getAttribute("data-dgmo-clock-fill-mode");
82847
83278
  let autoSolid = null;
82848
83279
  if (mode === "daylight") autoSolid = up ? c("day") : c("night");
82849
83280
  else if (mode === "time") autoSolid = rampColor(parts.h);
82850
83281
  else if (mode) autoSolid = group.getAttribute("data-dgmo-clock-auto-solid");
82851
- const faceFill = autoSolid && cardFill ? mix(autoSolid, cardFill, 20) : group.getAttribute("data-dgmo-clock-auto-face") ?? stTint;
82852
- const handColor = autoSolid ?? stColor;
82853
- const face = group.querySelector("[data-dgmo-clock-facebg]");
82854
- if (face) face.setAttribute("fill", faceFill);
82855
- const ring = group.querySelector("[data-dgmo-clock-facering]");
82856
- if (ring && autoSolid) ring.setAttribute("stroke", autoSolid);
82857
- const center = group.querySelector("[data-dgmo-clock-center]");
82858
- if (center) center.setAttribute("fill", handColor);
82859
- const secondHand = group.querySelector('[data-dgmo-clock-hand="s"]');
82860
- if (secondHand) secondHand.setAttribute("stroke", handColor);
83282
+ if (!fillMode) {
83283
+ const faceFill = autoSolid && cardFill ? mix(autoSolid, cardFill, 20) : group.getAttribute("data-dgmo-clock-auto-face") ?? stTint;
83284
+ const handColor = autoSolid ?? stColor;
83285
+ const face = group.querySelector("[data-dgmo-clock-facebg]");
83286
+ if (face) face.setAttribute("fill", faceFill);
83287
+ const ring = group.querySelector("[data-dgmo-clock-facering]");
83288
+ if (ring && autoSolid) ring.setAttribute("stroke", autoSolid);
83289
+ const center = group.querySelector("[data-dgmo-clock-center]");
83290
+ if (center) center.setAttribute("fill", handColor);
83291
+ const secondHand = group.querySelector('[data-dgmo-clock-hand="s"]');
83292
+ if (secondHand) secondHand.setAttribute("stroke", handColor);
83293
+ }
82861
83294
  setPart(group, '[data-dgmo-clock-digital-part="main"]', ts.main);
82862
83295
  setPart(group, '[data-dgmo-clock-digital-part="sec"]', `:${ts.sec}`);
82863
83296
  setPart(group, '[data-dgmo-clock-digital-part="ap"]', ts.ap);
@@ -82870,20 +83303,11 @@ function updateRow(group, now) {
82870
83303
  if (statusEl.textContent !== status.text)
82871
83304
  statusEl.textContent = status.text;
82872
83305
  statusEl.setAttribute("fill", col);
82873
- const dot = group.querySelector("[data-dgmo-clock-status-dot]");
82874
- if (dot) {
82875
- if (status.cls === "off") {
82876
- dot.setAttribute("fill", "none");
82877
- dot.setAttribute("stroke", col);
82878
- dot.setAttribute("stroke-width", "1.4");
82879
- } else {
82880
- dot.setAttribute("fill", col);
82881
- dot.setAttribute("stroke", "none");
82882
- }
82883
- }
83306
+ const icon = group.querySelector("[data-dgmo-clock-status-icon]");
83307
+ if (icon) icon.setAttribute("fill", col);
82884
83308
  }
82885
83309
  const lane = group.querySelector("[data-dgmo-clock-lane]");
82886
- if (lane && mode) {
83310
+ if (lane && mode && !fillMode) {
82887
83311
  let laneFill = null;
82888
83312
  if (mode === "daylight") laneFill = stTint;
82889
83313
  else if (mode === "time" && cardFill)
@@ -83058,7 +83482,7 @@ var parser = LRParser.deserialize({
83058
83482
  maxTerm: 40,
83059
83483
  skippedNodes: [0],
83060
83484
  repeatNodeCount: 2,
83061
- tokenData: "={~RzOX#uXY#zYZ$VZp#upq#zqr#urs$[st#uux#uxy%eyz%lz{%s{|%z|}&R}!O&Y!O!P#u!P!Q&i!Q!['Y![!]1Q!]!^#u!^!_1X!_!`1`!`!a1m!a!b1t!b!c#u!c!}1{!}#O5R#O#P#u#P#Q5W#Q#R#u#R#S1{#S#T#u#T#[1{#[#]5_#]#o1{#o#p#u#p#q=_#q#r#u#r#s=f#s;'S#u;'S;=`=u<%lO#u~#zOq~~$PQv~XY#zpq#z~$[Ow~~$aUq~OY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~$vUOY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~%_Oo~~%bP;=`<%l$s~%lOc~q~~%sOd~q~~%zOm~q~~&ROj~q~~&YOi~q~~&aPk~q~!`!a&d~&iOX~~&nPq~!P!Q&q~&vSV~OY&qZ;'S&q;'S;=`'S<%lO&q~'VP;=`<%l&q~'a^^~q~uv(]|}(b!O!P)_!P!Q+O!Q![,Y#R#S0l#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~(bO]~~(eP!Q![(h~(kP!Q![(n~(qP!Q![(t~(yQ^~|}(b!O!P)P~)SP!Q![)V~)[P^~!Q![)V~)bP!Q![)e~)jY^~uv(]!Q![)e#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~*]P#W#X*`~*ePZ~!a!b*h~*mOZ~~*rQZ~!a!b*h#]#^*x~*{P#b#c*`~+RP!Q![+U~+ZQ[~!P!Q+a!Q![,Q~+dP!Q![+g~+jP!Q![+m~+rP[~!Q![+u~+xP!Q![+{~,QO[~~,VP[~!P!Q+a~,_^^~uv(]|}(b!O!P)_!P!Q+O!Q![-Z#R#S0l#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~-`]^~uv(]|}(b!O!P)_!Q![.X#R#S0l#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~.^]^~uv(]}!O/V!O!P)_!Q![/q#R#S0l#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~/YP!Q![/]~/`P!Q![/c~/hP[~}!O/k~/nP!Q![+u~/v[^~uv(]!O!P)_!Q![/q#R#S0l#U#V*Y#W#X*`#[#]*`#a#b*m#e#f*`#g#h*`#k#l*`#m#n*`~0oP!Q![0r~0wR^~!O!P)P!Q![0r#R#S0l~1XOh~q~~1`Oe~q~~1ePq~!_!`1h~1mO_~~1tOf~q~~1{On~q~~2S_p~q~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#o3R~3W_p~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#o3R~4Y]qr3Rst3Rvw3Rwx3R{|3R!O!P3R!P!Q3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#o3R~5WOa~~5_Ob~q~~5fap~q~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#h3R#h#i6k#i#o3R~6pap~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#h3R#h#i7u#i#o3R~7zap~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#d3R#d#e9P#e#o3R~9Ubp~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R![!]:^!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#g3R#g#h<W#h#o3R~:aP!P!Q:d~:gP!P!Q:j~:mYOX;]Zp;]qy;]z|;]}!`;]!a#P;]#Q#p;]#q;'S;];'S;=`<Q<%lO;]~;bY`~OX;]Zp;]qy;]z|;]}!`;]!a#P;]#Q#p;]#q;'S;];'S;=`<Q<%lO;]~<TP;=`<%l;]~<]`p~qr3Rst3Rvw3Rwx3R{|3R}!O4V!O!P3R!P!Q3R!Q![3R![!]:^!_!`3R!a!b3R!b!c3R!c!}3R#R#S3R#T#o3R~=fOg~q~~=mPl~q~!`!a=p~=uOY~~=xP;=`<%l#u",
83485
+ tokenData: ">l~RzOX#uXY#zYZ$VZp#upq#zqr#urs$[st#uux#uxy%eyz%lz{%s{|%z|}&R}!O&Y!O!P#u!P!Q&i!Q!['Y![!]1q!]!^#u!^!_1x!_!`2P!`!a2^!a!b2e!b!c#u!c!}2l!}#O5r#O#P#u#P#Q5w#Q#R#u#R#S2l#S#T#u#T#[2l#[#]6O#]#o2l#o#p#u#p#q>O#q#r#u#r#s>V#s;'S#u;'S;=`>f<%lO#u~#zOq~~$PQv~XY#zpq#z~$[Ow~~$aUq~OY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~$vUOY$sZr$srs%Ys;'S$s;'S;=`%_<%lO$s~%_Oo~~%bP;=`<%l$s~%lOc~q~~%sOd~q~~%zOm~q~~&ROj~q~~&YOi~q~~&aPk~q~!`!a&d~&iOX~~&nPq~!P!Q&q~&vSV~OY&qZ;'S&q;'S;=`'S<%lO&q~'VP;=`<%l&q~'a_^~q~uv(`|}(e}!O)b!O!P*l!P!Q,]!Q![,v#R#S1]#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~(eO]~~(hP!Q![(k~(nP!Q![(q~(tP!Q![(w~(|Q^~|}(e!O!P)S~)VP!Q![)Y~)_P^~!Q![)Y~)eP!Q![)h~)mQ[~}!O)s!Q![*d~)vP!Q![)y~)|P!Q![*P~*UP[~!Q![*X~*[P!Q![*_~*dO[~~*iP[~}!O)s~*oP!Q![*r~*wY^~uv(`!Q![*r#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~+jP#W#X+m~+rPZ~!a!b+u~+zOZ~~,PQZ~!a!b+u#]#^,V~,YP#b#c+m~,`P!Q![,c~,hQ[~!P!Q)s!Q![,n~,sP[~!P!Q)s~,{_^~uv(`|}(e}!O)b!O!P*l!P!Q,]!Q![-z#R#S1]#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~.P]^~uv(`|}(e!O!P*l!Q![.x#R#S1]#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~.}]^~uv(`}!O/v!O!P*l!Q![0b#R#S1]#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~/yP!Q![/|~0PP!Q![0S~0XP[~}!O0[~0_P!Q![*X~0g[^~uv(`!O!P*l!Q![0b#R#S1]#U#V+g#W#X+m#[#]+m#a#b+z#e#f+m#g#h+m#k#l+m#m#n+m~1`P!Q![1c~1hR^~!O!P)S!Q![1c#R#S1]~1xOh~q~~2POe~q~~2UPq~!_!`2X~2^O_~~2eOf~q~~2lOn~q~~2s_p~q~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#o3r~3w_p~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#o3r~4y]qr3rst3rvw3rwx3r{|3r!O!P3r!P!Q3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#o3r~5wOa~~6OOb~q~~6Vap~q~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#h3r#h#i7[#i#o3r~7aap~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#h3r#h#i8f#i#o3r~8kap~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#d3r#d#e9p#e#o3r~9ubp~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r![!]:}!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#g3r#g#h<w#h#o3r~;QP!P!Q;T~;WP!P!Q;Z~;^YOX;|Zp;|qy;|z|;|}!`;|!a#P;|#Q#p;|#q;'S;|;'S;=`<q<%lO;|~<RY`~OX;|Zp;|qy;|z|;|}!`;|!a#P;|#Q#p;|#q;'S;|;'S;=`<q<%lO;|~<tP;=`<%l;|~<|`p~qr3rst3rvw3rwx3r{|3r}!O4v!O!P3r!P!Q3r!Q![3r![!]:}!_!`3r!a!b3r!b!c3r!c!}3r#R#S3r#T#o3r~>VOg~q~~>^Pl~q~!`!a>a~>fOY~~>iP;=`<%l#u",
83062
83486
  tokenizers: [0],
83063
83487
  topRules: { "Document": [0, 6] },
83064
83488
  specialized: [{ term: 32, get: (value, stack) => specializeKeyword(value, stack) << 1, external: specializeKeyword }],
@@ -83068,6 +83492,7 @@ var parser = LRParser.deserialize({
83068
83492
  // src/editor/highlight-api.ts
83069
83493
  init_directives_registry();
83070
83494
  init_resolve2();
83495
+ init_date();
83071
83496
  var NODE_TO_ROLE = {
83072
83497
  Comment: "comment",
83073
83498
  ChartType: "chartType",
@@ -83171,6 +83596,7 @@ function highlightDgmo(source) {
83171
83596
  applyLabelOverrides(tokens);
83172
83597
  applyNoteContent(tokens);
83173
83598
  applyRecurringLine(tokens);
83599
+ applyMonthNameDates(tokens);
83174
83600
  return tokens;
83175
83601
  }
83176
83602
  var ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
@@ -83405,6 +83831,40 @@ function applyRecurringLine(tokens) {
83405
83831
  offset += lineText.length + 1;
83406
83832
  }
83407
83833
  }
83834
+ var DATE_BEARING_CHARTS = /* @__PURE__ */ new Set([
83835
+ "gantt",
83836
+ "pert",
83837
+ "countdown",
83838
+ "timeline",
83839
+ "event-line"
83840
+ ]);
83841
+ function applyMonthNameDates(tokens) {
83842
+ const fullText = tokens.map((t) => t.text).join("");
83843
+ const lines = fullText.split("\n");
83844
+ const firstContent = lines.find((l) => {
83845
+ const t = l.trim();
83846
+ return t.length > 0 && !t.startsWith("//");
83847
+ });
83848
+ const chartType = firstContent?.trim().split(/\s+/)[0]?.toLowerCase();
83849
+ if (!chartType || !DATE_BEARING_CHARTS.has(chartType)) return;
83850
+ let offset = 0;
83851
+ for (const lineText of lines) {
83852
+ for (const sp of scanMonthNameDates(lineText)) {
83853
+ markDateSpan(tokens, offset + sp.start, offset + sp.end);
83854
+ }
83855
+ offset += lineText.length + 1;
83856
+ }
83857
+ }
83858
+ function markDateSpan(tokens, from, to) {
83859
+ let pos = 0;
83860
+ for (const token of tokens) {
83861
+ const tokenEnd = pos + token.text.length;
83862
+ if (tokenEnd > from && pos < to && token.text.trim().length > 0 && (token.role === "default" || token.role === "number")) {
83863
+ token.role = "number";
83864
+ }
83865
+ pos = tokenEnd;
83866
+ }
83867
+ }
83408
83868
  var NOTE_HEAD_RE = /^note(\s|$)/i;
83409
83869
  function applyNoteContent(tokens) {
83410
83870
  const fullText = tokens.map((t) => t.text).join("");
@@ -83971,7 +84431,7 @@ var CSS = AUTO_BASE_CSS + "\n" + BLOCK_CSS + "\n" + darkScopedBlockCss(BLOCK_CSS
83971
84431
 
83972
84432
  // src/auto/shared.ts
83973
84433
  init_safe_href();
83974
- var VERSION = "0.51.0";
84434
+ var VERSION = "0.52.0";
83975
84435
  var ARIA_LABEL_MAX = 200;
83976
84436
  var COPIED_INTERACTION_MS = 1500;
83977
84437
  var LOG_PREFIX = "[dgmo]";