tadforce 0.0.0-stage → 0.3.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 (141) hide show
  1. package/.claude-plugin/marketplace.json +20 -0
  2. package/.claude-plugin/plugin.json +13 -0
  3. package/LICENSE +202 -0
  4. package/NOTICE +11 -0
  5. package/README.md +266 -2
  6. package/assets/logo-mark.svg +24 -0
  7. package/assets/logo.svg +31 -0
  8. package/bin/tadforce.js +4 -0
  9. package/commands/tadforce-review.md +8 -0
  10. package/commands/tadforce-update.md +6 -0
  11. package/commands/tadforce.md +10 -0
  12. package/package.json +60 -4
  13. package/skills/tadforce/SKILL.md +73 -0
  14. package/skills/tadforce/references/axes-rules.md +29 -0
  15. package/skills/tadforce/references/evidence-rules.md +40 -0
  16. package/skills/tadforce/references/exclusion-heuristics.md +40 -0
  17. package/skills/tadforce/references/figure-rules.md +42 -0
  18. package/skills/tadforce/references/markdown-conventions.md +67 -0
  19. package/skills/tadforce/references/modules/agentforce-ai.md +24 -0
  20. package/skills/tadforce/references/modules/analytics.md +19 -0
  21. package/skills/tadforce/references/modules/commerce.md +25 -0
  22. package/skills/tadforce/references/modules/data-cloud.md +23 -0
  23. package/skills/tadforce/references/modules/experience-cloud.md +24 -0
  24. package/skills/tadforce/references/modules/field-service.md +25 -0
  25. package/skills/tadforce/references/modules/industries.md +21 -0
  26. package/skills/tadforce/references/modules/integration-platforms.md +19 -0
  27. package/skills/tadforce/references/modules/marketing.md +24 -0
  28. package/skills/tadforce/references/modules/omnistudio.md +24 -0
  29. package/skills/tadforce/references/modules/platform-events.md +19 -0
  30. package/skills/tadforce/references/modules/revenue-cpq.md +25 -0
  31. package/skills/tadforce/references/modules/sales-cloud.md +26 -0
  32. package/skills/tadforce/references/modules/security-shield.md +18 -0
  33. package/skills/tadforce/references/modules/service-cloud.md +27 -0
  34. package/skills/tadforce/references/naming-external-systems.md +32 -0
  35. package/skills/tadforce/references/questions.md +59 -0
  36. package/skills/tadforce/references/salesforce-skills.md +27 -0
  37. package/skills/tadforce/references/workflow.md +95 -0
  38. package/skills/tadforce/references/writing-rules.md +47 -0
  39. package/skills/tadforce-review/SKILL.md +53 -0
  40. package/skills/tadforce-update/SKILL.md +48 -0
  41. package/src/build/brand.js +107 -0
  42. package/src/build/browser.js +70 -0
  43. package/src/build/directives.js +293 -0
  44. package/src/build/export.js +60 -0
  45. package/src/build/figures.js +119 -0
  46. package/src/build/mermaid.js +107 -0
  47. package/src/build/render.js +299 -0
  48. package/src/build/serve.js +59 -0
  49. package/src/cli.js +68 -0
  50. package/src/commands/docs.js +204 -0
  51. package/src/commands/doctor.js +370 -0
  52. package/src/commands/init.js +132 -0
  53. package/src/commands/org.js +151 -0
  54. package/src/commands/review.js +35 -0
  55. package/src/commands/spec.js +91 -0
  56. package/src/commands/update.js +154 -0
  57. package/src/facts/extractors/apex.js +111 -0
  58. package/src/facts/extractors/automation.js +85 -0
  59. package/src/facts/extractors/data.js +94 -0
  60. package/src/facts/extractors/integration.js +76 -0
  61. package/src/facts/extractors/misc.js +100 -0
  62. package/src/facts/extractors/security.js +92 -0
  63. package/src/facts/extractors/ui.js +120 -0
  64. package/src/facts/fingerprints.js +32 -0
  65. package/src/facts/heuristics/exclusions.js +143 -0
  66. package/src/facts/heuristics/modules.js +85 -0
  67. package/src/facts/heuristics/naming.js +31 -0
  68. package/src/facts/heuristics/signals.js +76 -0
  69. package/src/facts/index.js +197 -0
  70. package/src/facts/org.js +87 -0
  71. package/src/facts/xml.js +85 -0
  72. package/src/sf/sf.js +120 -0
  73. package/src/util/args.js +21 -0
  74. package/src/util/config.js +104 -0
  75. package/src/util/fsx.js +58 -0
  76. package/src/util/i18n.js +49 -0
  77. package/src/util/log.js +31 -0
  78. package/src/util/paths.js +11 -0
  79. package/src/validate/index.js +126 -0
  80. package/templates/axes/en/00-document-control.md +3 -0
  81. package/templates/axes/en/01-summary.md +7 -0
  82. package/templates/axes/en/02-method.md +9 -0
  83. package/templates/axes/en/03-findings.md +19 -0
  84. package/templates/axes/en/04-register.md +3 -0
  85. package/templates/axes/en/05-roadmap.md +3 -0
  86. package/templates/axes/en/99-appendix.md +5 -0
  87. package/templates/axes/fr/00-document-control.md +3 -0
  88. package/templates/axes/fr/01-summary.md +7 -0
  89. package/templates/axes/fr/02-method.md +9 -0
  90. package/templates/axes/fr/03-findings.md +19 -0
  91. package/templates/axes/fr/04-register.md +3 -0
  92. package/templates/axes/fr/05-roadmap.md +3 -0
  93. package/templates/axes/fr/99-appendix.md +5 -0
  94. package/templates/html/cover.html +12 -0
  95. package/templates/html/editor.js +502 -0
  96. package/templates/html/style.css +255 -0
  97. package/templates/html/template.html +88 -0
  98. package/templates/i18n/en.json +366 -0
  99. package/templates/i18n/fr.json +366 -0
  100. package/templates/manifest/package-tad.xml +543 -0
  101. package/templates/specs/sections.yml +494 -0
  102. package/templates/tad/en/00-document-control.md +7 -0
  103. package/templates/tad/en/01-summary.md +17 -0
  104. package/templates/tad/en/02-purpose.md +35 -0
  105. package/templates/tad/en/03-context.md +17 -0
  106. package/templates/tad/en/04-general.md +29 -0
  107. package/templates/tad/en/05-functional.md +7 -0
  108. package/templates/tad/en/06-data.md +71 -0
  109. package/templates/tad/en/07-application.md +49 -0
  110. package/templates/tad/en/08-ui.md +41 -0
  111. package/templates/tad/en/09-integrations.md +53 -0
  112. package/templates/tad/en/10-security.md +59 -0
  113. package/templates/tad/en/11-reporting.md +13 -0
  114. package/templates/tad/en/12-operations.md +25 -0
  115. package/templates/tad/en/13-nfr.md +9 -0
  116. package/templates/tad/en/14-decisions.md +3 -0
  117. package/templates/tad/en/15-outlook.md +3 -0
  118. package/templates/tad/en/99-appendices.md +119 -0
  119. package/templates/tad/fr/00-document-control.md +7 -0
  120. package/templates/tad/fr/01-summary.md +17 -0
  121. package/templates/tad/fr/02-purpose.md +35 -0
  122. package/templates/tad/fr/03-context.md +17 -0
  123. package/templates/tad/fr/04-general.md +29 -0
  124. package/templates/tad/fr/05-functional.md +7 -0
  125. package/templates/tad/fr/06-data.md +71 -0
  126. package/templates/tad/fr/07-application.md +49 -0
  127. package/templates/tad/fr/08-ui.md +41 -0
  128. package/templates/tad/fr/09-integrations.md +53 -0
  129. package/templates/tad/fr/10-security.md +59 -0
  130. package/templates/tad/fr/11-reporting.md +13 -0
  131. package/templates/tad/fr/12-operations.md +25 -0
  132. package/templates/tad/fr/13-nfr.md +9 -0
  133. package/templates/tad/fr/14-decisions.md +3 -0
  134. package/templates/tad/fr/15-outlook.md +3 -0
  135. package/templates/tad/fr/99-appendices.md +119 -0
  136. package/templates/vendor/LICENSE-html-docx-js.txt +21 -0
  137. package/templates/vendor/LICENSE-html2canvas.txt +22 -0
  138. package/templates/vendor/LICENSE-mermaid.txt +21 -0
  139. package/templates/vendor/html-docx.js +13216 -0
  140. package/templates/vendor/html2canvas.min.js +20 -0
  141. package/templates/vendor/mermaid.min.js +2314 -0
@@ -0,0 +1,255 @@
1
+ :root{
2
+ --bg:#f5f7fb; --panel:#ffffff; --ink:#18212d; --muted:#5a6878; --line:#dde4ee;
3
+ --brand:#0B2545; --accent:#3D5AFE; --accent2:#9B1FE8;
4
+ --code:#eef2f8; --th:#0f2a4d; --thInk:#ffffff; --zebra:#f8fafd;
5
+ --side:#f4f7fc; --sideInk:#1b2632; --sideMuted:#5a6878; --sideHover:#e4ebf7; --sideLine:#dde4ee;
6
+ --card:#ffffff; --cardLine:#e3e9f2; --int:#f3efff; --intLine:#8b5cf6; --note:#eef6ff; --noteLine:#2f6fe4;
7
+ --reco:#ecfaf1; --recoLine:#2e9e5b; --fig:#ffffff;
8
+ --grad:linear-gradient(90deg,#1E88FF,#9B1FE8);
9
+ --shadow:0 1px 2px rgba(16,32,56,.05),0 6px 20px rgba(16,32,56,.06);
10
+ }
11
+ *{box-sizing:border-box}
12
+ html{scroll-behavior:smooth;scroll-padding-top:16px}
13
+ body{margin:0;background:var(--bg);color:var(--ink);font:15px/1.62 "Segoe UI",system-ui,-apple-system,Roboto,Arial,sans-serif;-webkit-text-size-adjust:100%}
14
+ a{color:var(--accent);text-decoration:none} a:hover{text-decoration:underline}
15
+ code{font-family:Consolas,"Cascadia Mono","SFMono-Regular",Menlo,monospace;font-size:.86em;background:var(--code);padding:.08em .35em;border-radius:4px;overflow-wrap:anywhere}
16
+
17
+ /* Sidebar */
18
+ #side{position:fixed;inset:0 auto 0 0;width:300px;background:var(--side);color:var(--sideInk);display:flex;flex-direction:column;z-index:30;border-right:1px solid var(--sideLine)}
19
+ .brand{display:flex;gap:12px;align-items:center;padding:16px 18px;border-bottom:1px solid var(--sideLine)}
20
+ .logo-int{width:46px;height:46px;border-radius:10px;background:#fff;padding:3px;flex:none}
21
+ .bt{font-weight:700;font-size:14px;line-height:1.25}.bs{font-size:11.5px;color:var(--sideMuted);margin-top:2px}
22
+ .search{padding:12px 14px 4px}
23
+ #q{width:100%;padding:8px 11px;border-radius:8px;border:1px solid var(--sideLine);background:#fff;color:var(--sideInk);font-size:13px;outline:none}
24
+ #q:focus{border-color:#6e8cff}
25
+ .toc{list-style:none;margin:6px 0 0;padding:4px 8px 10px;overflow:auto;flex:1}
26
+ .toc ul{list-style:none;margin:0;padding:0 0 4px 10px}
27
+ .toc a{display:block;color:var(--sideInk);padding:4px 10px;border-radius:6px;font-size:13px;line-height:1.35}
28
+ .toc li.l1>a{font-weight:600;margin-top:4px}
29
+ .toc li.l2 a{color:var(--sideMuted);font-size:12.5px}
30
+ .toc a:hover,.toc a.on{background:var(--sideHover);color:var(--brand);text-decoration:none}
31
+ .toc a.on{box-shadow:inset 3px 0 0 #8b5cf6}
32
+ .toc .num{color:var(--accent2);margin-right:4px;font-variant-numeric:tabular-nums}
33
+ .figs{padding:0 14px 8px;font-size:12.5px;color:var(--sideMuted);max-height:30vh;overflow:auto}
34
+ .figs summary{cursor:pointer;padding:6px 0;color:var(--sideInk)}
35
+ .figs ul{list-style:none;margin:0;padding:0}.figs a{color:var(--sideMuted);display:block;padding:2px 0}
36
+ .side-foot{display:grid;grid-template-columns:1fr 1fr;gap:6px;padding:10px 12px;border-top:1px solid var(--sideLine);background:#eef2f9}
37
+ .side-foot button{background:#fff;color:var(--sideInk);border:1px solid #cdd7e6;border-radius:8px;padding:7px 6px;font-size:12.5px;cursor:pointer;font-family:inherit}
38
+ .side-foot button:hover{background:var(--sideHover)}
39
+ #burger{display:none;position:fixed;top:10px;left:10px;z-index:40;background:#fff;color:#0B2545;box-shadow:0 2px 8px rgba(16,32,56,.15);border:0;border-radius:8px;width:42px;height:42px;font-size:20px;cursor:pointer}
40
+
41
+ /* Main */
42
+ #main{margin-left:300px;padding:28px 40px 60px;max-width:1260px}
43
+ .doc{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:12px 44px 40px;box-shadow:var(--shadow)}
44
+ .doc h1{font-size:26px;color:var(--brand);margin:46px 0 14px;padding-top:22px;border-top:3px solid transparent;border-image:var(--grad) 1;line-height:1.25}
45
+ .doc h1:first-child{margin-top:10px}
46
+ .doc h2{font-size:19.5px;color:var(--brand);margin:34px 0 10px;line-height:1.3}
47
+ .doc h3{font-size:16px;margin:24px 0 8px;color:var(--ink)}
48
+ .doc h4{margin:0 0 6px;font-size:15px}
49
+ .num{color:var(--accent2);font-weight:700;margin-right:6px;font-variant-numeric:tabular-nums}
50
+ .anchor{opacity:0;margin-left:8px;font-size:.7em;color:var(--muted)} h1:hover .anchor,h2:hover .anchor,h3:hover .anchor{opacity:1}
51
+ .doc p,.doc li{max-width:92ch}
52
+ .doc ul,.doc ol{padding-left:24px}.doc li{margin:3px 0}
53
+
54
+ /* Tables */
55
+ .tw{overflow-x:auto;margin:12px 0 18px;border:1px solid var(--line);border-radius:10px}
56
+ table{border-collapse:collapse;width:100%;font-size:13.6px;line-height:1.45}
57
+ th{background:var(--th);color:var(--thInk);text-align:left;font-weight:600;padding:9px 11px;vertical-align:bottom}
58
+ th code{background:rgba(255,255,255,.18);color:#ffffff}
59
+ td{padding:8px 11px;border-top:1px solid var(--line);vertical-align:top}
60
+ tbody tr:nth-child(even) td{background:var(--zebra)}
61
+ td[style*="right"],th[style*="right"]{font-variant-numeric:tabular-nums;white-space:nowrap}
62
+
63
+ /* Figures */
64
+ figure.diagram{margin:20px 0 24px;break-inside:avoid}
65
+ .fig-body{background:var(--fig);border:1px solid var(--line);border-radius:12px;padding:18px;overflow-x:auto;text-align:center}
66
+ .fig-body svg{max-width:100%;height:auto}
67
+ figcaption{font-size:13px;color:var(--muted);text-align:center;margin-top:8px;font-style:italic}
68
+ .mmd-error{color:#b00020;white-space:pre-wrap;text-align:left}
69
+
70
+ /* Cover */
71
+ .cover{background:var(--panel);border:1px solid var(--line);border-radius:14px;padding:38px 44px;margin-bottom:24px;box-shadow:var(--shadow);position:relative;overflow:hidden}
72
+ .cover::before{content:"";position:absolute;inset:0 0 auto 0;height:6px;background:var(--grad)}
73
+ .cover-logos{display:flex;justify-content:space-between;align-items:center;gap:20px;margin-bottom:26px}
74
+ .cover-logos img{height:64px;width:auto;background:#fff;border-radius:10px;padding:4px}
75
+ .cover .kicker{text-transform:uppercase;letter-spacing:.12em;font-size:12.5px;color:var(--accent2);font-weight:700}
76
+ .cover h1.ctitle{font-size:34px;line-height:1.15;margin:8px 0 6px;color:var(--brand);border:0;padding:0}
77
+ .cover .csub{font-size:18px;color:var(--muted);margin:0 0 22px}
78
+ .meta{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:10px;margin-top:10px}
79
+ .meta div{border:1px solid var(--line);border-radius:10px;padding:10px 12px}
80
+ .meta b{display:block;font-size:11.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);font-weight:600}
81
+ .meta span{font-weight:600}
82
+ .conf{margin-top:18px;font-size:12.5px;color:var(--muted)}
83
+
84
+ /* KPI tiles & cards */
85
+ .kpis{display:grid;grid-template-columns:repeat(auto-fit,minmax(170px,1fr));gap:12px;margin:18px 0 8px}
86
+ .kpi{border:1px solid var(--cardLine);background:var(--card);border-radius:12px;padding:14px 16px;position:relative;overflow:hidden}
87
+ .kpi::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--grad)}
88
+ .kpi b{display:block;font-size:26px;line-height:1.1;color:var(--brand);font-variant-numeric:tabular-nums}
89
+ .kpi span{font-size:12.8px;color:var(--muted)}
90
+ .cards{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:14px;margin:14px 0}
91
+ .card{border:1px solid var(--cardLine);background:var(--card);border-radius:12px;padding:16px 18px;break-inside:avoid}
92
+ .card h4{color:var(--brand)} .card p{margin:0;font-size:14px;color:var(--ink)}
93
+ .legend{display:flex;flex-wrap:wrap;gap:8px;margin:10px 0 6px}
94
+ .lg{font-size:12.8px;padding:4px 10px;border-radius:999px;border:1.5px solid}
95
+ .lg.actor{background:#F1E8FF;border-color:#7B3FE4;color:#2A1458}.lg.sf{background:#E8F1FF;border-color:#2F6FE4;color:#0B2545}
96
+ .lg.ext{background:#FFF2E2;border-color:#E0861F;color:#4A2A05}.lg.data{background:#E7F6EC;border-color:#2E9E5B;color:#0E3B22}
97
+
98
+ /* Callouts */
99
+ .callout{border-left:4px solid var(--intLine);background:var(--int);border-radius:0 10px 10px 0;padding:12px 16px;margin:16px 0;break-inside:avoid}
100
+ .callout .ct{font-weight:700;font-size:12.5px;text-transform:uppercase;letter-spacing:.06em;color:var(--intLine);margin-bottom:4px}
101
+ .callout p{margin:4px 0}
102
+ .callout.note{border-color:var(--noteLine);background:var(--note)}.callout.note .ct{color:var(--noteLine)}
103
+ .callout.reco{border-color:var(--recoLine);background:var(--reco)}.callout.reco .ct{color:var(--recoLine)}
104
+
105
+ /* Priority badges (improvement axes) */
106
+ .b{display:inline-block;font-size:11.5px;font-weight:700;padding:1px 8px;border-radius:999px;white-space:nowrap}
107
+ .b.p1{background:#fde2e7;color:#a3123a}.b.p2{background:#fff0d6;color:#8a5200}.b.p3{background:#e3f1ff;color:#0b4f9c}
108
+ .doc-foot{text-align:center;color:var(--muted);font-size:12.5px;margin-top:18px}
109
+
110
+ /* Responsive */
111
+ @media (max-width:980px){
112
+ #side{transform:translateX(-100%);transition:transform .2s}
113
+ body.nav-open #side{transform:none}
114
+ #burger{display:block}
115
+ #main{margin-left:0;padding:62px 16px 40px}
116
+ .doc{padding:8px 18px 28px}.cover{padding:26px 18px}
117
+ .cover h1.ctitle{font-size:26px}.cover-logos img{height:48px}
118
+ }
119
+
120
+ /* Print */
121
+ @page{size:A4;margin:16mm 14mm 18mm 14mm;
122
+ @bottom-left{content:"{{PRINT_FOOTER}}";font:9px "Segoe UI",Arial;color:#6b7a8c}
123
+ @bottom-right{content:"{{PRINT_PAGE}} " counter(page) " / " counter(pages);font:9px "Segoe UI",Arial;color:#6b7a8c}}
124
+ @page:first{@bottom-left{content:none}@bottom-right{content:none}}
125
+ @media print{
126
+ :root{--bg:#fff;--panel:#fff;--ink:#18212d;--muted:#5a6878;--line:#d6dde8;--brand:#0B2545;--th:#0f2a4d;--thInk:#fff;--zebra:#f6f8fb;--code:#eef2f8;--card:#fff;--cardLine:#d6dde8;--int:#f5f1ff;--note:#f0f6ff;--reco:#eefaf2;--fig:#fff}
127
+ html{scroll-behavior:auto}
128
+ body{background:#fff;font-size:10.4pt;-webkit-print-color-adjust:exact;print-color-adjust:exact}
129
+ #side,#burger,.anchor{display:none!important}
130
+ #main{margin:0;padding:0;max-width:none}
131
+ .doc{border:0;box-shadow:none;padding:0;border-radius:0}
132
+ .cover{border:0;box-shadow:none;min-height:255mm;display:flex;flex-direction:column;justify-content:center;break-after:page;padding:0 6mm}
133
+ .cover::before{height:8px}
134
+ .doc h1{break-before:page;margin-top:0;padding-top:10px;font-size:20pt}
135
+ .doc h2{font-size:14pt;break-after:avoid}.doc h3{break-after:avoid}
136
+ .tw{overflow:visible;border-radius:0}
137
+ table{font-size:8.8pt} th,td{padding:5px 7px} tr{break-inside:avoid} thead{display:table-header-group}
138
+ .fig-body{border:0;padding:4px}
139
+ .fig-body svg{max-height:225mm}
140
+ .kpi b{font-size:18pt}
141
+ .doc-foot{display:none}
142
+ a{color:inherit}
143
+ }
144
+
145
+ /* Layered architecture block */
146
+ .layers{display:flex;flex-direction:column;gap:8px;margin:18px 0 6px}
147
+ .layer{display:grid;grid-template-columns:150px 1fr;border:1px solid #c9d8f2;border-radius:10px;overflow:hidden;background:#E8F1FF;break-inside:avoid}
148
+ .layer .ln{background:#2F6FE4;color:#fff;font-weight:700;padding:10px 12px;display:flex;align-items:center;font-size:14px}
149
+ .layer .li{display:flex;flex-wrap:wrap;gap:8px;padding:10px 12px}
150
+ .layer .li span{background:#fff;border:1px solid #b9cdf0;border-radius:8px;padding:5px 10px;font-size:13px;color:#0B2545}
151
+ .layer.data{background:#E7F6EC;border-color:#bfe3cc}.layer.data .ln{background:#2E9E5B}.layer.data .li span{border-color:#bfe3cc;color:#0E3B22}
152
+ .layer.int{background:#FFF2E2;border-color:#f1d2a8}.layer.int .ln{background:#E0861F}.layer.int .li span{border-color:#f1d2a8;color:#4A2A05}
153
+ .figcap{font-size:13px;color:var(--muted);text-align:center;font-style:italic;margin:6px 0 20px}
154
+ @media (max-width:640px){.layer{grid-template-columns:1fr}}
155
+ @media print{.cover-logos img{height:24mm}.cover .kicker{font-size:11pt}.cover h1.ctitle{font-size:30pt}.cover .csub{font-size:14pt}}
156
+
157
+ /* Editor UI */
158
+ .figs summary{color:var(--sideInk)}
159
+ .print-wrap{grid-column:1/-1;position:relative}
160
+ .print-wrap>button{width:100%;background:#0B2545!important;color:#fff!important;border-color:#0B2545!important}
161
+ #btnSave.dirty{background:#fff4d6;border-color:#e0a800;font-weight:600}
162
+ #btnSave.dirty::after{content:" •";color:#d97706}
163
+ body.editing #btnEdit{background:#ede6ff;border-color:#8b5cf6;font-weight:600}
164
+ .cnt{display:inline-block;min-width:18px;padding:0 5px;border-radius:999px;background:#e3e9f5;font-size:11px;font-weight:700}
165
+ .menu{display:none;position:absolute;bottom:42px;left:0;right:0;background:#fff;border:1px solid #cdd7e6;border-radius:10px;box-shadow:0 8px 24px rgba(16,32,56,.15);padding:6px;z-index:60}
166
+ .menu.on{display:block}
167
+ .menu button{display:block;width:100%;text-align:left;border:0!important;background:transparent!important;padding:9px 10px!important}
168
+ .menu button:hover{background:var(--sideHover)!important}
169
+ .edit-banner{display:none;position:fixed;top:0;left:300px;right:0;z-index:35;background:#7B3FE4;color:#fff;font-size:13px;padding:7px 16px;text-align:center}
170
+ body.editing .edit-banner{display:block}
171
+ body.editing #main{padding-top:46px}
172
+ body.editing .doc,body.editing .cover{outline:2px dashed #8b5cf6;outline-offset:4px}
173
+ body.editing [data-edited]{background:#fffbe6}
174
+ [contenteditable="true"]:focus{outline:none}
175
+ mark.tad-cmt{background:#fff1a8;color:inherit;border-bottom:2px solid #e0a800;padding:0 1px;cursor:pointer;border-radius:2px}
176
+ mark.tad-cmt.resolved{background:#e3f5e9;border-bottom-color:#2e9e5b}
177
+ mark.tad-cmt.flash{background:#ffd54f;box-shadow:0 0 0 2px #ffb300}
178
+ #cmtPanel{position:fixed;top:0;right:0;bottom:0;width:380px;background:#fff;border-left:1px solid var(--line);box-shadow:-8px 0 24px rgba(16,32,56,.08);z-index:50;display:flex;flex-direction:column;transform:translateX(105%);transition:transform .2s}
179
+ body.panel-open #cmtPanel{transform:none}
180
+ body.panel-open #main{margin-right:380px}
181
+ .cmt-head{display:flex;justify-content:space-between;align-items:center;padding:14px 16px;border-bottom:1px solid var(--line);font-size:15px;color:var(--brand)}
182
+ .cmt-head button{border:0;background:none;font-size:16px;cursor:pointer;color:var(--muted)}
183
+ .cmt-help{font-size:12.5px;color:var(--muted);margin:10px 16px 0}
184
+ .cmt-edited{font-size:12.5px;color:#8a5200;margin:6px 16px 0}
185
+ #cmtList{flex:1;overflow:auto;padding:10px 12px}
186
+ .cmt-empty{color:var(--muted);font-size:13px;padding:8px}
187
+ .cmt-item{border:1px solid var(--line);border-left:4px solid #e0a800;border-radius:8px;padding:9px 11px;margin-bottom:10px;font-size:13px}
188
+ .cmt-item.done{border-left-color:#2e9e5b;opacity:.75}
189
+ .cmt-item.active{box-shadow:0 0 0 2px #ffd54f}
190
+ .cmt-h{display:flex;gap:6px;align-items:baseline;color:var(--muted);font-size:12px}
191
+ .cmt-h span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
192
+ .cmt-h em{font-style:normal;font-weight:600}
193
+ .cmt-item blockquote{margin:6px 0;padding:4px 8px;background:#fffbe6;border-radius:4px;font-size:12.5px;color:#4a3b00;max-height:5.4em;overflow:hidden}
194
+ .cmt-t{padding:4px 6px;border-radius:4px;border:1px solid transparent;white-space:pre-wrap}
195
+ .cmt-t:hover,.cmt-t:focus{border-color:var(--line);outline:none}
196
+ .cmt-a{display:flex;gap:6px;margin-top:6px}
197
+ .cmt-a button,.cmt-foot button,.pop-a button{font:inherit;font-size:12px;background:#fff;border:1px solid #cdd7e6;border-radius:6px;padding:4px 9px;cursor:pointer}
198
+ .cmt-a button:hover,.cmt-foot button:hover,.pop-a button:hover{background:var(--sideHover)}
199
+ .cmt-foot{padding:10px 12px;border-top:1px solid var(--line)}
200
+ .cmt-foot button{width:100%;padding:8px}
201
+ #cmtPop{display:none;position:fixed;z-index:70;width:360px;background:#fff;border:1px solid #cdd7e6;border-radius:12px;box-shadow:0 12px 32px rgba(16,32,56,.2);padding:12px}
202
+ #cmtPop.on{display:block}
203
+ .pop-quote{font-size:12.5px;color:#4a3b00;background:#fffbe6;border-radius:6px;padding:6px 8px;margin-bottom:8px;max-height:4.5em;overflow:hidden}
204
+ #cmtPop textarea{width:100%;font:inherit;font-size:13.5px;border:1px solid #cdd7e6;border-radius:8px;padding:8px;resize:vertical}
205
+ .pop-a{display:flex;justify-content:flex-end;gap:8px;margin-top:8px}
206
+ .pop-a .primary{background:#0B2545;color:#fff;border-color:#0B2545}
207
+ #toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(20px);background:#0B2545;color:#fff;padding:10px 16px;border-radius:10px;font-size:13.5px;opacity:0;pointer-events:none;transition:all .2s;z-index:80;max-width:min(680px,92vw);text-align:center}
208
+ #toast.on{opacity:1;transform:translateX(-50%)}
209
+ @media (max-width:980px){.edit-banner{left:0}#cmtPanel{width:100%}body.panel-open #main{margin-right:0}}
210
+ @media print{#cmtPanel,#cmtPop,#toast,.edit-banner,.menu{display:none!important}mark.tad-cmt{background:none!important;border:0!important;padding:0}[data-edited]{background:none!important}body.panel-open #main{margin-right:0}.doc,.cover{outline:0!important}}
211
+
212
+ /* Comment mode & capture */
213
+ #cmtBar{display:none;position:fixed;top:0;left:300px;right:0;z-index:45;background:#fff8db;border-bottom:2px solid #e0a800;color:#4a3b00;font-size:13.5px;padding:8px 16px;align-items:center;gap:10px;flex-wrap:wrap}
214
+ #cmtBar span{flex:1;min-width:240px}
215
+ #cmtBar button{font:inherit;font-size:12.5px;border:1px solid #d9b84a;background:#fff;border-radius:7px;padding:5px 10px;cursor:pointer}
216
+ #cmtBar #cbarCapture{background:#0B2545;color:#fff;border-color:#0B2545;font-weight:600}
217
+ body.commenting #cmtBar{display:flex}
218
+ body.commenting #main{padding-top:52px}
219
+ body.commenting .doc,body.commenting .cover{cursor:text;outline:2px dashed #e0a800;outline-offset:4px}
220
+ #btnComment.on{background:#fff4d6;border-color:#e0a800;font-weight:600}
221
+ #capOverlay{display:none;position:fixed;inset:0;z-index:90;cursor:crosshair;background:rgba(11,37,69,.08)}
222
+ #capOverlay.on{display:block}
223
+ .cap-hint{position:fixed;top:12px;left:50%;transform:translateX(-50%);background:#0B2545;color:#fff;font-size:13px;padding:8px 14px;border-radius:8px;pointer-events:none}
224
+ #capBox{display:none;position:fixed;border:2px solid #e0a800;background:rgba(255,213,79,.15);box-shadow:0 0 0 9999px rgba(11,37,69,.25)}
225
+ .tad-pin{display:inline-block;font-size:12px;line-height:1;padding:2px 4px;margin-right:6px;border-radius:6px;background:#fff1a8;border:1px solid #e0a800;cursor:pointer;vertical-align:middle;font-style:normal}
226
+ .tad-pin.resolved{background:#e3f5e9;border-color:#2e9e5b}
227
+ .tad-pin.flash{box-shadow:0 0 0 3px #ffb300}
228
+ .pop-img img{display:block;max-width:100%;max-height:160px;margin:0 auto 8px;border:1px solid #cdd7e6;border-radius:6px}
229
+ .pop-a .sp{flex:1}
230
+ .pop-a .cap{background:#f4f7fc}
231
+ .cmt-img{display:block;max-width:100%;max-height:150px;margin:6px 0;border:1px solid var(--line);border-radius:6px;cursor:zoom-in}
232
+ #lightbox{display:none;position:fixed;inset:0;z-index:95;background:rgba(11,37,69,.75);align-items:center;justify-content:center;cursor:zoom-out;padding:24px}
233
+ #lightbox.on{display:flex}
234
+ #lightbox img{max-width:100%;max-height:100%;background:#fff;border-radius:8px;box-shadow:0 12px 40px rgba(0,0,0,.4)}
235
+ @media (max-width:980px){#cmtBar{left:0}}
236
+ @media print{#cmtBar,#capOverlay,#lightbox,.tad-pin{display:none!important}}
237
+
238
+ .cap-wait{font-size:12.5px;color:#5a6878;background:#f4f7fc;border:1px dashed #cdd7e6;border-radius:6px;padding:14px;text-align:center;margin-bottom:8px}
239
+
240
+ /* Clickable KPI tiles */
241
+ a.kpi{display:block;color:inherit;text-decoration:none;transition:border-color .15s,box-shadow .15s,transform .15s}
242
+ a.kpi:hover{text-decoration:none;border-color:#8b5cf6;box-shadow:0 4px 14px rgba(123,63,228,.15);transform:translateY(-1px)}
243
+ a.kpi::after{content:var(--kpiMore);display:block;margin-top:6px;font-size:11.5px;color:var(--accent2);opacity:0;transition:opacity .15s}
244
+ a.kpi:hover::after{opacity:1}
245
+ @media print{a.kpi::after{display:none}}
246
+
247
+ .cmt-r{margin-top:6px;padding:6px 8px;background:#e7f6ec;border-radius:6px;font-size:12.5px;color:#0e3b22}
248
+
249
+ /* Sections still to be written */
250
+ .pending{border:1.5px dashed #c9b3f5;background:#faf7ff;color:#5b3ea8;border-radius:10px;padding:12px 16px;margin:12px 0;font-size:13.5px}
251
+ .pending code{background:#efe7ff}
252
+ @media print{.pending{border-color:#bbb;color:#777;background:none}}
253
+
254
+ /* Generated text logo (no logo file provided) */
255
+ .logo-txt{display:inline-flex;align-items:center;justify-content:center}
@@ -0,0 +1,88 @@
1
+ <!doctype html>
2
+ <html lang="{{LANG}}">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="generator" content="TADForce {{VERSION}}">
7
+ <title>{{TITLE}}</title>
8
+ <meta name="description" content="{{DESCRIPTION}}">
9
+ <style>{{CSS}}</style>
10
+ <style>{{BRAND_CSS}}</style>
11
+ </head>
12
+ <body>
13
+ <nav id="side" aria-label="{{T:ui.toc}}">
14
+ <div class="brand">
15
+ <img src="{{INTEGRATOR_LOGO}}" alt="{{INTEGRATOR_NAME}}" class="logo-int">
16
+ <div><div class="bt">{{SIDE_TITLE}}</div><div class="bs">{{SIDE_SUB}}</div></div>
17
+ </div>
18
+ <div class="search"><input id="q" type="search" placeholder="{{T:ui.tocFilter}}" aria-label="{{T:ui.tocFilter}}"></div>
19
+ <ul class="toc" id="toc">{{TOC}}</ul>
20
+ <details class="figs"><summary>{{T:ui.figures}}</summary><ul>{{FIGLIST}}</ul></details>
21
+ <div class="side-foot">
22
+ <button type="button" id="btnEdit" title="{{T:ui.editTitle}}">{{T:ui.edit}}</button>
23
+ <button type="button" id="btnComment" title="{{T:ui.commentTitle}}">{{T:ui.comment}}</button>
24
+ <button type="button" id="btnPanel" title="{{T:ui.commentsTitle}}">{{T:ui.comments}} <span id="cmtCount" class="cnt">0</span></button>
25
+ <button type="button" id="btnSave" title="{{T:ui.saveTitle}}">{{T:ui.save}}</button>
26
+ <div class="print-wrap">
27
+ <button type="button" id="btnPrint" title="{{T:ui.printTitle}}">{{T:ui.print}}</button>
28
+ <div id="printMenu" class="menu" role="menu">
29
+ <button type="button" id="doPdf" role="menuitem">{{T:ui.pdf}}</button>
30
+ <button type="button" id="doDocx" role="menuitem">{{T:ui.docx}}</button>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ </nav>
35
+ <button type="button" id="burger" aria-label="{{T:ui.burger}}">☰</button>
36
+ <div id="cmtBar"><span>{{T:ui.commentBar}}</span>
37
+ <button type="button" id="cbarCapture" title="{{T:ui.captureTitle}}">{{T:ui.capture}}</button>
38
+ <button type="button" id="cbarCancel">{{T:ui.cancelEsc}}</button></div>
39
+ <div id="capOverlay"><div class="cap-hint">{{T:ui.captureHint}}</div><div id="capBox"></div></div>
40
+ <div id="lightbox" title="{{T:ui.lightbox}}"><img id="lightboxImg" alt=""></div>
41
+ <div class="edit-banner">{{T:ui.editBanner}}</div>
42
+ <main id="main">
43
+ <section class="cover">
44
+ <div class="cover-logos">{{COVER_LOGOS}}</div>
45
+ {{COVER}}
46
+ </section>
47
+ <article class="doc">
48
+ {{BODY}}
49
+ </article>
50
+ <footer class="doc-foot">{{FOOTER}}</footer>
51
+ </main>
52
+ <aside id="cmtPanel" aria-label="{{T:ui.panelTitle}}">
53
+ <div class="cmt-head"><b>{{T:ui.panelTitle}}</b><button type="button" id="cmtClose" aria-label="{{T:ui.close}}">✕</button></div>
54
+ <p class="cmt-help">{{T:ui.panelHelp}}</p>
55
+ <p id="cmtEdited" class="cmt-edited"></p>
56
+ <div id="cmtList"></div>
57
+ <div class="cmt-foot"><button type="button" id="cmtCopy">{{T:ui.copyList}}</button></div>
58
+ </aside>
59
+ <div id="cmtPop" role="dialog" aria-label="{{T:ui.newComment}}">
60
+ <div id="cmtPopQuote" class="pop-quote"></div>
61
+ <div id="cmtPopImg" class="pop-img"></div>
62
+ <textarea id="cmtPopText" rows="4" placeholder="{{T:ui.commentPlaceholder}}"></textarea>
63
+ <div class="pop-a"><button type="button" id="cmtAddCap" class="cap">{{T:ui.attachCapture}}</button><span class="sp"></span><button type="button" id="cmtCancel">{{T:ui.cancel}}</button><button type="button" id="cmtOk" class="primary">{{T:ui.add}}</button></div>
64
+ </div>
65
+ <div id="toast" role="status" aria-live="polite"></div>
66
+ <script type="application/json" id="tad-comments">[]</script>
67
+ <script>window.TAD_I18N={{I18N_JSON}};window.TAD_BRAND={{BRAND_JSON}};</script>
68
+ <script>
69
+ (function(){
70
+ document.getElementById('burger').addEventListener('click',function(){document.body.classList.toggle('nav-open');});
71
+ document.querySelectorAll('#side a').forEach(function(a){a.addEventListener('click',function(){document.body.classList.remove('nav-open');});});
72
+ var q=document.getElementById('q');
73
+ q.addEventListener('input',function(){
74
+ var v=q.value.trim().toLowerCase();
75
+ document.querySelectorAll('#toc li').forEach(function(li){li.style.display=(!v||li.textContent.toLowerCase().indexOf(v)>=0)?'':'none';});
76
+ });
77
+ var links={}; document.querySelectorAll('#toc a').forEach(function(a){links[a.getAttribute('href').slice(1)]=a;});
78
+ var io=new IntersectionObserver(function(es){es.forEach(function(e){
79
+ if(e.isIntersecting&&links[e.target.id]){document.querySelectorAll('#toc a.on').forEach(function(x){x.classList.remove('on');});links[e.target.id].classList.add('on');}
80
+ });},{rootMargin:'0px 0px -75% 0px'});
81
+ document.querySelectorAll('.doc h1[id], .doc h2[id]').forEach(function(h){io.observe(h);});
82
+ })();
83
+ </script>
84
+ <script>{{DOCX_LIB}}</script>
85
+ <script>{{CAPTURE_LIB}}</script>
86
+ <script>{{EDITOR_JS}}</script>
87
+ </body>
88
+ </html>