dimcode-darwin-x64 0.1.2 → 0.1.3-beta.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 (148) hide show
  1. package/bin/dimcode +0 -0
  2. package/bin/runtime/sandbox/dim-sandbox-runner +0 -0
  3. package/bin/runtime/sandbox/manifest.json +15 -0
  4. package/bin/skills-assets/deep-investigate/SKILL.md +101 -0
  5. package/bin/skills-assets/deep-investigate/references/prompts.md +75 -0
  6. package/bin/skills-assets/deep-investigate/references/templates.md +73 -0
  7. package/bin/skills-assets/deep-investigate/references/thinking-tools.md +36 -0
  8. package/bin/skills-assets/docs-sprint/SKILL.md +73 -0
  9. package/bin/skills-assets/docs-sprint/agents/openai.yaml +4 -0
  10. package/bin/skills-assets/docs-sprint/references/contract-discipline.md +30 -0
  11. package/bin/skills-assets/docs-sprint/references/delivery-plan.md +162 -0
  12. package/bin/skills-assets/docs-sprint/references/documentation-system.md +109 -0
  13. package/bin/skills-assets/docs-sprint/references/ui-layout.md +73 -0
  14. package/bin/skills-assets/docs-sprint/references/worktree-guide.md +45 -0
  15. package/bin/skills-assets/docx/SKILL.md +273 -0
  16. package/bin/skills-assets/docx/assets/styles/academic_styles.xml +250 -0
  17. package/bin/skills-assets/docx/assets/styles/corporate_styles.xml +284 -0
  18. package/bin/skills-assets/docx/assets/styles/default_styles.xml +449 -0
  19. package/bin/skills-assets/docx/assets/xsd/aesthetic-rules.xsd +470 -0
  20. package/bin/skills-assets/docx/assets/xsd/business-rules.xsd +130 -0
  21. package/bin/skills-assets/docx/assets/xsd/common-types.xsd +159 -0
  22. package/bin/skills-assets/docx/assets/xsd/wml-subset.xsd +589 -0
  23. package/bin/skills-assets/docx/references/cjk_typography.md +357 -0
  24. package/bin/skills-assets/docx/references/cjk_university_template_guide.md +184 -0
  25. package/bin/skills-assets/docx/references/comments_guide.md +191 -0
  26. package/bin/skills-assets/docx/references/design_good_bad_examples.md +829 -0
  27. package/bin/skills-assets/docx/references/design_principles.md +819 -0
  28. package/bin/skills-assets/docx/references/openxml_element_order.md +308 -0
  29. package/bin/skills-assets/docx/references/openxml_encyclopedia_part1.md +4061 -0
  30. package/bin/skills-assets/docx/references/openxml_encyclopedia_part2.md +2820 -0
  31. package/bin/skills-assets/docx/references/openxml_encyclopedia_part3.md +3381 -0
  32. package/bin/skills-assets/docx/references/openxml_namespaces.md +82 -0
  33. package/bin/skills-assets/docx/references/openxml_units.md +72 -0
  34. package/bin/skills-assets/docx/references/scenario_a_create.md +284 -0
  35. package/bin/skills-assets/docx/references/scenario_b_edit_content.md +295 -0
  36. package/bin/skills-assets/docx/references/scenario_c_apply_template.md +456 -0
  37. package/bin/skills-assets/docx/references/track_changes_guide.md +200 -0
  38. package/bin/skills-assets/docx/references/troubleshooting.md +506 -0
  39. package/bin/skills-assets/docx/references/typography_guide.md +294 -0
  40. package/bin/skills-assets/docx/references/xsd_validation_guide.md +158 -0
  41. package/bin/skills-assets/docx/scripts/doc_to_docx.sh +40 -0
  42. package/bin/skills-assets/docx/scripts/docx_preview.sh +37 -0
  43. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Docx.Cli.csproj +19 -0
  44. package/bin/skills-assets/docx/scripts/dotnet/Docx.Cli/Program.cs +18 -0
  45. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/AnalyzeCommand.cs +147 -0
  46. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ApplyTemplateCommand.cs +322 -0
  47. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/CreateCommand.cs +324 -0
  48. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/DiffCommand.cs +155 -0
  49. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/EditContentCommand.cs +487 -0
  50. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/FixOrderCommand.cs +108 -0
  51. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/MergeRunsCommand.cs +122 -0
  52. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Commands/ValidateCommand.cs +107 -0
  53. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Docx.Core.csproj +15 -0
  54. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/CommentSynchronizer.cs +169 -0
  55. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/ElementOrder.cs +80 -0
  56. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/NamespaceConstants.cs +42 -0
  57. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/RunMerger.cs +81 -0
  58. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/StyleAnalyzer.cs +81 -0
  59. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/TrackChangesHelper.cs +99 -0
  60. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/OpenXml/UnitConverter.cs +23 -0
  61. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples.cs +1832 -0
  62. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch1.cs +910 -0
  63. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch2.cs +999 -0
  64. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch3.cs +1048 -0
  65. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/AestheticRecipeSamples_Batch4.cs +1038 -0
  66. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/CharacterFormattingSamples.cs +1020 -0
  67. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/DocumentCreationSamples.cs +1121 -0
  68. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FieldAndTocSamples.cs +624 -0
  69. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/FootnoteAndCommentSamples.cs +675 -0
  70. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/HeaderFooterSamples.cs +838 -0
  71. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ImageSamples.cs +917 -0
  72. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ListAndNumberingSamples.cs +826 -0
  73. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/ParagraphFormattingSamples.cs +1199 -0
  74. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/StyleSystemSamples.cs +1487 -0
  75. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TableSamples.cs +1163 -0
  76. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Samples/TrackChangesSamples.cs +595 -0
  77. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/CjkHelper.cs +39 -0
  78. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/FontDefaults.cs +24 -0
  79. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Typography/PageSizes.cs +20 -0
  80. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/BusinessRuleValidator.cs +224 -0
  81. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/GateCheckValidator.cs +148 -0
  82. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/ValidationResult.cs +23 -0
  83. package/bin/skills-assets/docx/scripts/dotnet/Docx.Core/Validation/XsdValidator.cs +69 -0
  84. package/bin/skills-assets/docx/scripts/dotnet/Docx.slnx +4 -0
  85. package/bin/skills-assets/docx/scripts/env_check.sh +196 -0
  86. package/bin/skills-assets/docx/scripts/setup.ps1 +274 -0
  87. package/bin/skills-assets/docx/scripts/setup.sh +504 -0
  88. package/bin/skills-assets/pdf/README.md +222 -0
  89. package/bin/skills-assets/pdf/SKILL.md +191 -0
  90. package/bin/skills-assets/pdf/design/design.md +381 -0
  91. package/bin/skills-assets/pdf/scripts/cover.py +1579 -0
  92. package/bin/skills-assets/pdf/scripts/fill_inspect.py +200 -0
  93. package/bin/skills-assets/pdf/scripts/fill_write.py +242 -0
  94. package/bin/skills-assets/pdf/scripts/make.sh +491 -0
  95. package/bin/skills-assets/pdf/scripts/merge.py +112 -0
  96. package/bin/skills-assets/pdf/scripts/palette.py +521 -0
  97. package/bin/skills-assets/pdf/scripts/reformat_parse.py +374 -0
  98. package/bin/skills-assets/pdf/scripts/render_body.py +1052 -0
  99. package/bin/skills-assets/pdf/scripts/render_cover.js +111 -0
  100. package/bin/skills-assets/pptx-generator/SKILL.md +248 -0
  101. package/bin/skills-assets/pptx-generator/references/design-system.md +392 -0
  102. package/bin/skills-assets/pptx-generator/references/editing.md +162 -0
  103. package/bin/skills-assets/pptx-generator/references/pitfalls.md +112 -0
  104. package/bin/skills-assets/pptx-generator/references/pptxgenjs.md +420 -0
  105. package/bin/skills-assets/pptx-generator/references/slide-types.md +413 -0
  106. package/bin/skills-assets/skill-creator/SKILL.md +368 -0
  107. package/bin/skills-assets/skill-creator/agents/openai.yaml +5 -0
  108. package/bin/skills-assets/skill-creator/assets/skill-creator-small.svg +3 -0
  109. package/bin/skills-assets/skill-creator/assets/skill-creator.png +0 -0
  110. package/bin/skills-assets/skill-creator/license.txt +202 -0
  111. package/bin/skills-assets/skill-creator/references/openai_yaml.md +49 -0
  112. package/bin/skills-assets/skill-creator/scripts/generate_openai_yaml.py +226 -0
  113. package/bin/skills-assets/skill-creator/scripts/init_skill.py +397 -0
  114. package/bin/skills-assets/skill-creator/scripts/quick_validate.py +101 -0
  115. package/bin/skills-assets/skill-installer/LICENSE.txt +202 -0
  116. package/bin/skills-assets/skill-installer/SKILL.md +58 -0
  117. package/bin/skills-assets/skill-installer/agents/openai.yaml +5 -0
  118. package/bin/skills-assets/skill-installer/assets/skill-installer-small.svg +3 -0
  119. package/bin/skills-assets/skill-installer/assets/skill-installer.png +0 -0
  120. package/bin/skills-assets/skill-installer/scripts/github_utils.py +21 -0
  121. package/bin/skills-assets/skill-installer/scripts/install-skill-from-github.py +308 -0
  122. package/bin/skills-assets/skill-installer/scripts/list-skills.py +107 -0
  123. package/bin/skills-assets/xlsx/SKILL.md +137 -0
  124. package/bin/skills-assets/xlsx/references/create.md +691 -0
  125. package/bin/skills-assets/xlsx/references/edit.md +684 -0
  126. package/bin/skills-assets/xlsx/references/fix.md +37 -0
  127. package/bin/skills-assets/xlsx/references/format.md +768 -0
  128. package/bin/skills-assets/xlsx/references/ooxml-cheatsheet.md +231 -0
  129. package/bin/skills-assets/xlsx/references/read-analyze.md +97 -0
  130. package/bin/skills-assets/xlsx/references/validate.md +772 -0
  131. package/bin/skills-assets/xlsx/scripts/formula_check.py +422 -0
  132. package/bin/skills-assets/xlsx/scripts/libreoffice_recalc.py +248 -0
  133. package/bin/skills-assets/xlsx/scripts/shared_strings_builder.py +163 -0
  134. package/bin/skills-assets/xlsx/scripts/style_audit.py +575 -0
  135. package/bin/skills-assets/xlsx/scripts/xlsx_add_column.py +395 -0
  136. package/bin/skills-assets/xlsx/scripts/xlsx_insert_row.py +274 -0
  137. package/bin/skills-assets/xlsx/scripts/xlsx_pack.py +87 -0
  138. package/bin/skills-assets/xlsx/scripts/xlsx_reader.py +362 -0
  139. package/bin/skills-assets/xlsx/scripts/xlsx_shift_rows.py +396 -0
  140. package/bin/skills-assets/xlsx/scripts/xlsx_unpack.py +130 -0
  141. package/bin/skills-assets/xlsx/templates/minimal_xlsx/[Content_Types].xml +9 -0
  142. package/bin/skills-assets/xlsx/templates/minimal_xlsx/_rels/.rels +6 -0
  143. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/_rels/workbook.xml.rels +19 -0
  144. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/sharedStrings.xml +33 -0
  145. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/styles.xml +160 -0
  146. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/workbook.xml +30 -0
  147. package/bin/skills-assets/xlsx/templates/minimal_xlsx/xl/worksheets/sheet1.xml +70 -0
  148. package/package.json +1 -1
@@ -0,0 +1,521 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ palette.py — Infer design tokens from document metadata.
4
+
5
+ Usage:
6
+ python3 palette.py --title "AI Trends 2025" --type report --out tokens.json
7
+ python3 palette.py --title "John Doe Resume" --type resume --out tokens.json
8
+ python3 palette.py --meta meta.json --out tokens.json
9
+
10
+ Outputs tokens.json consumed by all downstream scripts.
11
+ Cover fonts are loaded via Google Fonts @import in the cover HTML (no local caching).
12
+ Body fonts always use ReportLab system fonts (Times-Bold / Helvetica).
13
+ Exit codes: 0 success, 1 bad args, 3 write error
14
+ """
15
+
16
+ import argparse
17
+ import json
18
+ import sys
19
+
20
+ # ── Palette library ────────────────────────────────────────────────────────────
21
+ # Each entry: cover colors + cover_pattern + mood
22
+ PALETTES = {
23
+ "report": {
24
+ # Charcoal blue-grey cover; muted steel blue accent — authoritative, not flashy
25
+ "cover_bg": "#1B2A38",
26
+ "accent": "#3B6D8A",
27
+ "accent_lt": "#E6EFF5",
28
+ "text_light": "#EDE9E2",
29
+ "page_bg": "#FAFAF8",
30
+ "dark": "#1A1E24",
31
+ "body_text": "#2C2C30",
32
+ "muted": "#7A7A84",
33
+ "cover_pattern": "fullbleed",
34
+ "mood": "authoritative",
35
+ },
36
+ "proposal": {
37
+ # Dark charcoal cover; slate grey-blue accent — confident, understated
38
+ "cover_bg": "#22272E",
39
+ "accent": "#4E6070",
40
+ "accent_lt": "#EAECEE",
41
+ "text_light": "#EDE9E2",
42
+ "page_bg": "#FAFAF7",
43
+ "dark": "#18191E",
44
+ "body_text": "#28282E",
45
+ "muted": "#7A7870",
46
+ "cover_pattern": "split",
47
+ "mood": "confident",
48
+ },
49
+ "resume": {
50
+ # White; deep navy accent — clean and unambiguous
51
+ "cover_bg": "#FFFFFF",
52
+ "accent": "#1C3557",
53
+ "accent_lt": "#E8EEF5",
54
+ "text_light": "#FFFFFF",
55
+ "page_bg": "#FFFFFF",
56
+ "dark": "#111111",
57
+ "body_text": "#222222",
58
+ "muted": "#888888",
59
+ "cover_pattern": "typographic",
60
+ "mood": "clean",
61
+ },
62
+ "portfolio": {
63
+ # Near-black charcoal; cool slate grey accent — subdued professional
64
+ "cover_bg": "#191C20",
65
+ "accent": "#6A7A88",
66
+ "accent_lt": "#EAECEE",
67
+ "text_light": "#EDE9E4",
68
+ "page_bg": "#F8F8F8",
69
+ "dark": "#18191E",
70
+ "body_text": "#28282E",
71
+ "muted": "#8A8A96",
72
+ "cover_pattern": "atmospheric",
73
+ "mood": "expressive",
74
+ },
75
+ "academic": {
76
+ # Warm white; classic navy accent — scholarly standard
77
+ "cover_bg": "#F5F4F0",
78
+ "accent": "#2A436A",
79
+ "accent_lt": "#E6EBF4",
80
+ "text_light": "#FFFFFF",
81
+ "page_bg": "#F5F4F0",
82
+ "dark": "#1A1A28",
83
+ "body_text": "#1E1E2A",
84
+ "muted": "#686877",
85
+ "cover_pattern": "typographic",
86
+ "mood": "scholarly",
87
+ },
88
+ "general": {
89
+ # Dark slate; muted steel accent — neutral, no-nonsense
90
+ "cover_bg": "#1F2329",
91
+ "accent": "#4A6070",
92
+ "accent_lt": "#E6EAEC",
93
+ "text_light": "#EEEBE5",
94
+ "page_bg": "#F8F6F2",
95
+ "dark": "#1A1A1A",
96
+ "body_text": "#2C2C2C",
97
+ "muted": "#888888",
98
+ "cover_pattern": "fullbleed",
99
+ "mood": "neutral",
100
+ },
101
+ # ── Extended types — each uses a distinct new cover pattern ─────────────────
102
+ "minimal": {
103
+ # Warm off-white; dark neutral grey — truly restrained, no color signal
104
+ "cover_bg": "#F7F6F4",
105
+ "accent": "#4A4A4A",
106
+ "accent_lt": "#EBEBEA",
107
+ "text_light": "#F7F6F4",
108
+ "page_bg": "#F7F6F4",
109
+ "dark": "#111111",
110
+ "body_text": "#222222",
111
+ "muted": "#999999",
112
+ "cover_pattern": "minimal",
113
+ "mood": "restrained",
114
+ },
115
+ "stripe": {
116
+ # Near-black; charcoal slate accent — structured, no-nonsense
117
+ "cover_bg": "#1E222A",
118
+ "accent": "#4A5568",
119
+ "accent_lt": "#EAECEE",
120
+ "text_light": "#FFFFFF",
121
+ "page_bg": "#F8F8F7",
122
+ "dark": "#0E1117",
123
+ "body_text": "#262630",
124
+ "muted": "#888898",
125
+ "cover_pattern": "stripe",
126
+ "mood": "bold",
127
+ },
128
+ "diagonal": {
129
+ # Deep navy; muted slate-blue accent — dignified, controlled
130
+ "cover_bg": "#1A2535",
131
+ "accent": "#3D5A72",
132
+ "accent_lt": "#E4EBF0",
133
+ "text_light": "#EEF0F5",
134
+ "page_bg": "#F8FAFC",
135
+ "dark": "#0F1A2A",
136
+ "body_text": "#1E2C3A",
137
+ "muted": "#7A8A96",
138
+ "cover_pattern": "diagonal",
139
+ "mood": "dynamic",
140
+ },
141
+ "frame": {
142
+ # Warm parchment; dark muted brown — classical, formal
143
+ "cover_bg": "#F5F2EC",
144
+ "accent": "#5C4A38",
145
+ "accent_lt": "#EAE5DE",
146
+ "text_light": "#F5F2EC",
147
+ "page_bg": "#F5F2EC",
148
+ "dark": "#2A1E14",
149
+ "body_text": "#2C2018",
150
+ "muted": "#9A8A78",
151
+ "cover_pattern": "frame",
152
+ "mood": "classical",
153
+ },
154
+ "editorial": {
155
+ # White; deep burgundy accent — editorial weight without the shout
156
+ "cover_bg": "#FFFFFF",
157
+ "accent": "#7A2B36",
158
+ "accent_lt": "#EEE4E5",
159
+ "text_light": "#FFFFFF",
160
+ "page_bg": "#FFFFFF",
161
+ "dark": "#0A0A0A",
162
+ "body_text": "#1A1A1A",
163
+ "muted": "#777777",
164
+ "cover_pattern": "editorial",
165
+ "mood": "editorial",
166
+ },
167
+ # ── New patterns (v2) ────────────────────────────────────────────────────────
168
+ "magazine": {
169
+ # Warm linen; deep navy accent — formal publication standard
170
+ "cover_bg": "#F0EEE9",
171
+ "accent": "#1C3557",
172
+ "accent_lt": "#E4EBF3",
173
+ "text_light": "#FFFFFF",
174
+ "page_bg": "#F0EEE9",
175
+ "dark": "#0D1A2B",
176
+ "body_text": "#2A2A2A",
177
+ "muted": "#888888",
178
+ "cover_pattern": "magazine",
179
+ "mood": "magazine",
180
+ },
181
+ "darkroom": {
182
+ # Deep navy; muted steel-blue accent — premium, controlled
183
+ "cover_bg": "#151C27",
184
+ "accent": "#3D5A7A",
185
+ "accent_lt": "#E2EBF2",
186
+ "text_light": "#EDE9E2",
187
+ "page_bg": "#F7F7F5",
188
+ "dark": "#0A1018",
189
+ "body_text": "#2C2C2C",
190
+ "muted": "#8A9AB0",
191
+ "cover_pattern": "darkroom",
192
+ "mood": "darkroom",
193
+ },
194
+ "terminal": {
195
+ # Near-black; forest green accent — technical, serious (not neon)
196
+ "cover_bg": "#0D1117",
197
+ "accent": "#3D7A5C",
198
+ "accent_lt": "#E2EEE8",
199
+ "text_light": "#E6EDF3",
200
+ "page_bg": "#F8F8F6",
201
+ "dark": "#010409",
202
+ "body_text": "#2C2C2C",
203
+ "muted": "#5A7A6A",
204
+ "cover_pattern": "terminal",
205
+ "mood": "terminal",
206
+ },
207
+ "poster": {
208
+ # White; near-black accent sidebar — stark, unambiguous
209
+ "cover_bg": "#FFFFFF",
210
+ "accent": "#0A0A0A",
211
+ "accent_lt": "#EBEBEA",
212
+ "text_light": "#FFFFFF",
213
+ "page_bg": "#FFFFFF",
214
+ "dark": "#0A0A0A",
215
+ "body_text": "#1A1A1A",
216
+ "muted": "#888888",
217
+ "cover_pattern": "poster",
218
+ "mood": "poster",
219
+ },
220
+ }
221
+
222
+ # ── Font pairs — CSS names for cover HTML, ReportLab names for body ─────────────
223
+ # cover uses Google Fonts via @import (no local disk caching needed)
224
+ # body always uses system fonts via ReportLab
225
+ FONT_PAIRS = {
226
+ "authoritative": {
227
+ "display_css": "Playfair Display",
228
+ "body_css": "IBM Plex Sans",
229
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@700;900&family=IBM+Plex+Sans:ital,wght@0,400;0,600;1,400&display=swap",
230
+ "display_rl": "Times-Bold",
231
+ "body_rl": "Helvetica",
232
+ "body_b_rl": "Helvetica-Bold",
233
+ },
234
+ "confident": {
235
+ "display_css": "Syne",
236
+ "body_css": "Nunito Sans",
237
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Syne:wght@600;800&family=Nunito+Sans:wght@400;600;700&display=swap",
238
+ "display_rl": "Times-Bold",
239
+ "body_rl": "Helvetica",
240
+ "body_b_rl": "Helvetica-Bold",
241
+ },
242
+ "clean": {
243
+ "display_css": "DM Serif Display",
244
+ "body_css": "DM Sans",
245
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=DM+Serif+Display&family=DM+Sans:wght@300;400;500&display=swap",
246
+ "display_rl": "Times-Bold",
247
+ "body_rl": "Helvetica",
248
+ "body_b_rl": "Helvetica-Bold",
249
+ },
250
+ "expressive": {
251
+ "display_css": "Fraunces",
252
+ "body_css": "Inter",
253
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Fraunces:ital,wght@0,700;0,900;1,900&family=Inter:wght@300;400;500&display=swap",
254
+ "display_rl": "Times-Bold",
255
+ "body_rl": "Helvetica",
256
+ "body_b_rl": "Helvetica-Bold",
257
+ },
258
+ "scholarly": {
259
+ "display_css": "EB Garamond",
260
+ "body_css": "Source Sans 3",
261
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,700;1,400&family=Source+Sans+3:wght@400;600&display=swap",
262
+ "display_rl": "Times-Bold",
263
+ "body_rl": "Helvetica",
264
+ "body_b_rl": "Helvetica-Bold",
265
+ },
266
+ "neutral": {
267
+ "display_css": "Outfit",
268
+ "body_css": "Outfit",
269
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;700;900&display=swap",
270
+ "display_rl": "Times-Bold",
271
+ "body_rl": "Helvetica",
272
+ "body_b_rl": "Helvetica-Bold",
273
+ },
274
+ "restrained": {
275
+ "display_css": "Cormorant Garamond",
276
+ "body_css": "Jost",
277
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,300;0,600;1,300&family=Jost:wght@300;400;500&display=swap",
278
+ "display_rl": "Times-Bold",
279
+ "body_rl": "Helvetica",
280
+ "body_b_rl": "Helvetica-Bold",
281
+ },
282
+ "bold": {
283
+ "display_css": "Barlow Condensed",
284
+ "body_css": "Barlow",
285
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@700;900&family=Barlow:wght@400;500;600&display=swap",
286
+ "display_rl": "Times-Bold",
287
+ "body_rl": "Helvetica",
288
+ "body_b_rl": "Helvetica-Bold",
289
+ },
290
+ "dynamic": {
291
+ "display_css": "Montserrat",
292
+ "body_css": "Montserrat",
293
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,300;0,700;0,900;1,400&display=swap",
294
+ "display_rl": "Times-Bold",
295
+ "body_rl": "Helvetica",
296
+ "body_b_rl": "Helvetica-Bold",
297
+ },
298
+ "classical": {
299
+ "display_css": "Cormorant",
300
+ "body_css": "Crimson Pro",
301
+ "gfonts_import": "https://fonts.googleapis.com/css2?family=Cormorant:ital,wght@0,400;0,700;1,400&family=Crimson+Pro:wght@400;600&display=swap",
302
+ "display_rl": "Times-Bold",
303
+ "body_rl": "Helvetica",
304
+ "body_b_rl": "Helvetica-Bold",
305
+ },
306
+ "editorial": {
307
+ "display_css": "Bebas Neue",
308
+ "body_css": "Libre Franklin",
309
+ "gfonts_import": (
310
+ "https://fonts.googleapis.com/css2?family=Bebas+Neue"
311
+ "&family=Libre+Franklin:ital,wght@0,400;0,700;1,400&display=swap"
312
+ ),
313
+ "display_rl": "Times-Bold",
314
+ "body_rl": "Helvetica",
315
+ "body_b_rl": "Helvetica-Bold",
316
+ },
317
+ # ── New moods (v2) ───────────────────────────────────────────────────────────
318
+ "magazine": {
319
+ "display_css": "Playfair Display",
320
+ "body_css": "EB Garamond",
321
+ "gfonts_import": (
322
+ "https://fonts.googleapis.com/css2?family=Playfair+Display"
323
+ ":ital,wght@0,700;0,900;1,700"
324
+ "&family=EB+Garamond:ital,wght@0,400;0,600;1,400&display=swap"
325
+ ),
326
+ "display_rl": "Times-Bold",
327
+ "body_rl": "Helvetica",
328
+ "body_b_rl": "Helvetica-Bold",
329
+ },
330
+ "darkroom": {
331
+ "display_css": "Playfair Display",
332
+ "body_css": "EB Garamond",
333
+ "gfonts_import": (
334
+ "https://fonts.googleapis.com/css2?family=Playfair+Display"
335
+ ":ital,wght@0,700;0,900;1,700"
336
+ "&family=EB+Garamond:ital,wght@0,400;0,600;1,400&display=swap"
337
+ ),
338
+ "display_rl": "Times-Bold",
339
+ "body_rl": "Helvetica",
340
+ "body_b_rl": "Helvetica-Bold",
341
+ },
342
+ "terminal": {
343
+ "display_css": "Space Mono",
344
+ "body_css": "Space Mono",
345
+ "gfonts_import": (
346
+ "https://fonts.googleapis.com/css2?family=Space+Mono"
347
+ ":ital,wght@0,400;0,700;1,400&display=swap"
348
+ ),
349
+ "display_rl": "Courier-Bold",
350
+ "body_rl": "Courier",
351
+ "body_b_rl": "Courier-Bold",
352
+ },
353
+ "poster": {
354
+ "display_css": "Barlow Condensed",
355
+ "body_css": "Courier Prime",
356
+ "gfonts_import": (
357
+ "https://fonts.googleapis.com/css2?family=Barlow+Condensed"
358
+ ":wght@700;900"
359
+ "&family=Courier+Prime:ital,wght@0,400;0,700;1,400&display=swap"
360
+ ),
361
+ "display_rl": "Times-Bold",
362
+ "body_rl": "Courier",
363
+ "body_b_rl": "Courier-Bold",
364
+ },
365
+ }
366
+
367
+ SYSTEM_FALLBACK = {
368
+ "display_css": "Georgia",
369
+ "body_css": "Arial",
370
+ "gfonts_import": "",
371
+ "display_rl": "Times-Bold",
372
+ "body_rl": "Helvetica",
373
+ "body_b_rl": "Helvetica-Bold",
374
+ }
375
+
376
+
377
+ # ── Colour helpers ──────────────────────────────────────────────────────────────
378
+ def _hex_to_rgb(h: str) -> tuple:
379
+ h = h.lstrip("#")
380
+ return int(h[0:2], 16), int(h[2:4], 16), int(h[4:6], 16)
381
+
382
+
383
+ def _lighten(hex_color: str, factor: float = 0.09) -> str:
384
+ """Blend hex_color toward white (factor = accent weight, 0=white, 1=full color)."""
385
+ r, g, b = _hex_to_rgb(hex_color)
386
+ return "#{:02X}{:02X}{:02X}".format(
387
+ round(r * factor + 255 * (1 - factor)),
388
+ round(g * factor + 255 * (1 - factor)),
389
+ round(b * factor + 255 * (1 - factor)),
390
+ )
391
+
392
+
393
+ # ── Token assembly ─────────────────────────────────────────────────────────────
394
+ def build_tokens(
395
+ title: str,
396
+ doc_type: str,
397
+ author: str = "",
398
+ date: str = "",
399
+ accent_override: str = "",
400
+ cover_bg_override: str = "",
401
+ ) -> dict:
402
+ palette = PALETTES.get(doc_type, PALETTES["general"]).copy()
403
+ mood = palette["mood"]
404
+ font_pair = FONT_PAIRS.get(mood, SYSTEM_FALLBACK)
405
+
406
+ # Apply caller-supplied overrides before token assembly
407
+ if accent_override:
408
+ palette["accent"] = accent_override
409
+ palette["accent_lt"] = _lighten(accent_override, 0.09)
410
+ if cover_bg_override:
411
+ palette["cover_bg"] = cover_bg_override
412
+
413
+ tokens = {
414
+ # Identity
415
+ "title": title,
416
+ "author": author,
417
+ "date": date,
418
+ "doc_type": doc_type,
419
+
420
+ # Palette
421
+ "cover_bg": palette["cover_bg"],
422
+ "accent": palette["accent"],
423
+ "accent_lt": palette["accent_lt"],
424
+ "text_light": palette["text_light"],
425
+ "page_bg": palette["page_bg"],
426
+ "dark": palette["dark"],
427
+ "body_text": palette["body_text"],
428
+ "muted": palette["muted"],
429
+ "cover_pattern": palette["cover_pattern"],
430
+ "mood": mood,
431
+
432
+ # Typography — CSS names for cover HTML (loaded via Google Fonts @import)
433
+ "font_display": font_pair["display_css"],
434
+ "font_body": font_pair["body_css"],
435
+ "gfonts_import": font_pair["gfonts_import"],
436
+
437
+ # Typography — ReportLab system font names for body pages
438
+ "font_display_rl": font_pair["display_rl"],
439
+ "font_body_rl": font_pair["body_rl"],
440
+ "font_body_b_rl": font_pair["body_b_rl"],
441
+
442
+ # Legacy keys (kept so render_body.py's register_fonts is a no-op)
443
+ "font_heading": font_pair["display_rl"],
444
+ "font_body_b": font_pair["body_b_rl"],
445
+ "font_paths": {},
446
+
447
+ # Type scale (pt)
448
+ "size_display": 54,
449
+ "size_h1": 22,
450
+ "size_h2": 15,
451
+ "size_h3": 11.5,
452
+ "size_body": 10.5,
453
+ "size_caption": 8.5,
454
+ "size_meta": 8,
455
+
456
+ # Layout (pt, 1cm ≈ 28.35pt)
457
+ "margin_left": 79, # 2.8cm
458
+ "margin_right": 79,
459
+ "margin_top": 79,
460
+ "margin_bottom": 71, # 2.5cm
461
+ "section_gap": 26,
462
+ "para_gap": 8,
463
+ "line_gap": 17,
464
+ }
465
+ return tokens
466
+
467
+
468
+ # ── CLI ───────────────────────────────────────────────────────────────────────
469
+ def main():
470
+ parser = argparse.ArgumentParser(description="Generate design tokens from document metadata")
471
+ parser.add_argument("--title", default="Untitled Document")
472
+ parser.add_argument("--type", default="general",
473
+ choices=list(PALETTES.keys()),
474
+ help="Document type: " + ", ".join(PALETTES.keys()))
475
+ parser.add_argument("--author", default="")
476
+ parser.add_argument("--date", default="")
477
+ parser.add_argument("--meta", help="JSON file with title/type/author/date keys")
478
+ parser.add_argument("--accent", default="",
479
+ help="Override accent colour (hex, e.g. #2D6A8F). "
480
+ "accent_lt is auto-derived by lightening toward white.")
481
+ parser.add_argument("--cover-bg", default="",
482
+ help="Override cover background colour (hex).")
483
+ parser.add_argument("--out", default="tokens.json")
484
+ args = parser.parse_args()
485
+
486
+ if args.meta:
487
+ try:
488
+ with open(args.meta) as f:
489
+ meta = json.load(f)
490
+ args.title = meta.get("title", args.title)
491
+ args.type = meta.get("type", args.type)
492
+ args.author = meta.get("author", args.author)
493
+ args.date = meta.get("date", args.date)
494
+ except Exception as e:
495
+ print(json.dumps({"status": "error", "error": str(e)}), file=sys.stderr)
496
+ sys.exit(1)
497
+
498
+ tokens = build_tokens(
499
+ args.title, args.type, args.author, args.date,
500
+ accent_override=args.accent,
501
+ cover_bg_override=getattr(args, "cover_bg", ""),
502
+ )
503
+
504
+ try:
505
+ with open(args.out, "w") as f:
506
+ json.dump(tokens, f, indent=2)
507
+ except Exception as e:
508
+ print(json.dumps({"status": "error", "error": str(e)}), file=sys.stderr)
509
+ sys.exit(3)
510
+
511
+ print(json.dumps({
512
+ "status": "ok",
513
+ "out": args.out,
514
+ "mood": tokens["mood"],
515
+ "pattern": tokens["cover_pattern"],
516
+ "fonts": f'{tokens["font_display"]} / {tokens["font_body"]}',
517
+ }))
518
+
519
+
520
+ if __name__ == "__main__":
521
+ main()