@takazudo/zudo-doc 3.2.0 → 4.0.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 (439) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +2 -2
  3. package/bin/tag-cli-config.ts +126 -0
  4. package/bin/tags-audit-runner.ts +60 -76
  5. package/bin/tags-audit.mjs +17 -36
  6. package/bin/tags-suggest-runner.ts +429 -0
  7. package/bin/tags-suggest.mjs +30 -0
  8. package/bin/zudo-doc.mjs +78 -25
  9. package/dist/breadcrumb/breadcrumb.d.ts +4 -4
  10. package/dist/breadcrumb/find-path.d.ts +2 -2
  11. package/dist/breadcrumb/index.d.ts +1 -1
  12. package/dist/breadcrumb/types.d.ts +0 -5
  13. package/dist/chrome/derive.d.ts +16 -4
  14. package/dist/chrome/derive.js +64 -4
  15. package/dist/chrome/index.d.ts +13 -10
  16. package/dist/chrome/index.js +12 -6
  17. package/dist/chrome/primary-slots.d.ts +21 -0
  18. package/dist/chrome/primary-slots.js +59 -0
  19. package/dist/chrome-bindings.d.ts +227 -0
  20. package/dist/chrome-bindings.js +6 -0
  21. package/dist/code-syntax/code-block-enhancer-script.d.ts +4 -0
  22. package/dist/code-syntax/code-block-enhancer-script.js +7 -4
  23. package/dist/code-syntax/code-block-enhancer.d.ts +2 -2
  24. package/dist/code-syntax/code-block-enhancer.js +1 -3
  25. package/dist/code-syntax/index.d.ts +5 -5
  26. package/dist/code-syntax/index.js +4 -13
  27. package/dist/code-syntax/mermaid-init-script.d.ts +1 -22
  28. package/dist/code-syntax/mermaid-init-script.js +0 -2
  29. package/dist/code-syntax/mermaid-init.d.ts +0 -1
  30. package/dist/code-syntax/mermaid-init.js +3 -4
  31. package/dist/code-syntax/tabs-init.d.ts +0 -1
  32. package/dist/code-syntax/tabs-init.js +1 -3
  33. package/dist/code-syntax/tabs.d.ts +0 -1
  34. package/dist/code-syntax/tabs.js +1 -3
  35. package/dist/color-scheme-utils.d.ts +72 -4
  36. package/dist/color-scheme-utils.js +137 -0
  37. package/dist/color-schemes-defaults/index.d.ts +23 -0
  38. package/dist/color-schemes-defaults/index.js +134 -0
  39. package/dist/config.d.ts +459 -0
  40. package/dist/config.js +125 -0
  41. package/dist/content/component-map.d.ts +0 -16
  42. package/dist/content/component-map.js +2 -4
  43. package/dist/content/index.d.ts +1 -1
  44. package/dist/content/index.js +2 -3
  45. package/dist/content.css +1 -1
  46. package/dist/design-token-panel-bootstrap.d.ts +82 -27
  47. package/dist/design-token-panel-bootstrap.js +110 -21
  48. package/dist/design-token-panel-config/index.d.ts +49 -0
  49. package/dist/design-token-panel-config/index.js +211 -0
  50. package/dist/design-token-panel-config/manifest.d.ts +46 -0
  51. package/dist/design-token-panel-config/manifest.js +105 -0
  52. package/dist/directive-vocabulary-defaults/index.d.ts +16 -0
  53. package/dist/directive-vocabulary-defaults/index.js +12 -0
  54. package/dist/doc-body-end-islands/design-token-panel-island.d.ts +15 -0
  55. package/dist/doc-body-end-islands/design-token-panel-island.js +31 -0
  56. package/dist/doc-body-end-islands/index.d.ts +52 -7
  57. package/dist/doc-body-end-islands/index.js +19 -0
  58. package/dist/doc-body-end-islands/theme-pack-switcher-island.d.ts +37 -0
  59. package/dist/doc-body-end-islands/theme-pack-switcher-island.js +18 -0
  60. package/dist/doc-content-header/index.js +1 -1
  61. package/dist/doc-history-area/index.d.ts +10 -4
  62. package/dist/doc-history-area/index.js +3 -2
  63. package/dist/doc-metainfo-area/index.d.ts +1 -0
  64. package/dist/doc-page-props/index.d.ts +7 -23
  65. package/dist/doc-page-renderer/index.d.ts +1 -0
  66. package/dist/doc-page-renderer/index.js +1 -0
  67. package/dist/doc-page-shell/index.js +19 -12
  68. package/dist/doc-pager/index.js +1 -1
  69. package/dist/doc-route-entries/index.d.ts +2 -2
  70. package/dist/doclayout/doc-layout-with-defaults.js +4 -4
  71. package/dist/doclayout/doc-layout.d.ts +8 -0
  72. package/dist/doclayout/doc-layout.js +10 -1
  73. package/dist/docs-schema/index.d.ts +67 -0
  74. package/dist/docs-schema/index.js +43 -0
  75. package/dist/eject/index.d.ts +16 -0
  76. package/dist/eject/index.js +122 -28
  77. package/dist/extract-headings/index.d.ts +5 -8
  78. package/dist/extract-headings/index.js +2 -9
  79. package/dist/factory-context/index.d.ts +56 -4
  80. package/dist/features.css +65 -43
  81. package/dist/find-in-page/find-bar.d.ts +9 -0
  82. package/dist/find-in-page/find-bar.js +114 -0
  83. package/dist/find-in-page/find-in-page.d.ts +17 -0
  84. package/dist/find-in-page/find-in-page.js +131 -0
  85. package/dist/find-in-page/index.d.ts +11 -0
  86. package/dist/find-in-page/index.js +49 -0
  87. package/dist/footer/footer.js +1 -0
  88. package/dist/frontmatter-preview-defaults/index.d.ts +16 -0
  89. package/dist/frontmatter-preview-defaults/index.js +25 -0
  90. package/dist/head-with-defaults/index.d.ts +2 -0
  91. package/dist/head-with-defaults/index.js +16 -0
  92. package/dist/header/header.d.ts +10 -5
  93. package/dist/header/header.js +45 -5
  94. package/dist/header/index.d.ts +1 -1
  95. package/dist/header/types.d.ts +30 -1
  96. package/dist/header-with-defaults/index.js +1 -0
  97. package/dist/home-page/index.d.ts +2 -0
  98. package/dist/home-page/index.js +11 -5
  99. package/dist/home-page/prepare-home-data.js +1 -1
  100. package/dist/i18n-defaults/index.d.ts +22 -0
  101. package/dist/i18n-defaults/index.js +167 -0
  102. package/dist/locale-merge/index.d.ts +9 -14
  103. package/dist/locale-merge/index.js +6 -4
  104. package/dist/mdx-components/index.js +4 -4
  105. package/dist/plugins/claude-resources.d.ts +1 -0
  106. package/dist/plugins/claude-resources.js +4 -2
  107. package/dist/plugins/doc-history.js +1 -1
  108. package/dist/{integrations → plugins/internal}/claude-resources/index.d.ts +1 -16
  109. package/dist/{integrations → plugins/internal}/claude-resources/index.js +0 -9
  110. package/dist/{integrations → plugins/internal}/doc-history/index.d.ts +0 -17
  111. package/dist/{integrations → plugins/internal}/doc-history/index.js +0 -4
  112. package/dist/{integrations → plugins/internal}/doc-history/pre-build.d.ts +2 -4
  113. package/dist/plugins/internal/llms-txt/index.d.ts +7 -0
  114. package/dist/{integrations → plugins/internal}/llms-txt/load.d.ts +1 -1
  115. package/dist/{integrations → plugins/internal}/llms-txt/load.js +2 -2
  116. package/dist/{integrations → plugins/internal}/llms-txt/strip.d.ts +2 -3
  117. package/dist/{integrations → plugins/internal}/llms-txt/strip.js +1 -1
  118. package/dist/{integrations → plugins/internal}/llms-txt/types.d.ts +13 -22
  119. package/dist/{integrations → plugins/internal}/search-index/collect.js +1 -1
  120. package/dist/plugins/internal/theme-packs/copy.d.ts +32 -0
  121. package/dist/plugins/internal/theme-packs/copy.js +45 -0
  122. package/dist/plugins/internal/theme-packs/dev-middleware.d.ts +22 -0
  123. package/dist/plugins/internal/theme-packs/dev-middleware.js +80 -0
  124. package/dist/plugins/internal/theme-packs/index.d.ts +6 -0
  125. package/dist/plugins/internal/theme-packs/index.js +9 -0
  126. package/dist/plugins/internal/theme-packs/resolve.d.ts +17 -0
  127. package/dist/plugins/internal/theme-packs/resolve.js +17 -0
  128. package/dist/plugins/internal/theme-packs/types.d.ts +22 -0
  129. package/dist/plugins/internal/theme-packs/types.js +0 -0
  130. package/dist/plugins/llms-txt.js +1 -1
  131. package/dist/plugins/routes.js +55 -21
  132. package/dist/plugins/search-index.js +1 -1
  133. package/dist/plugins/theme-packs.d.ts +3 -0
  134. package/dist/plugins/theme-packs.js +40 -0
  135. package/dist/preset.d.ts +28 -14
  136. package/dist/preset.js +24 -9
  137. package/dist/route-context/index.js +4 -6
  138. package/dist/route-enumerators/index.d.ts +6 -18
  139. package/dist/route-enumerators/index.js +8 -6
  140. package/dist/routes/404.js +3 -1
  141. package/dist/routes/_chrome.js +3 -2
  142. package/dist/routes/_context.d.ts +7 -3
  143. package/dist/routes/_context.js +2 -0
  144. package/dist/routes/_docs-helpers.js +9 -21
  145. package/dist/safelist.css +1 -1
  146. package/dist/settings.d.ts +64 -12
  147. package/dist/sidebar-tree/build-tree.d.ts +3 -4
  148. package/dist/sidebar-tree/build-tree.js +4 -3
  149. package/dist/sidebar-tree/index.d.ts +2 -2
  150. package/dist/sidebar-tree/types.d.ts +6 -17
  151. package/dist/site-tree-nav-island/index.d.ts +3 -1
  152. package/dist/site-tree-nav-island/index.js +17 -5
  153. package/dist/site-tree-nav-island/state.d.ts +4 -0
  154. package/dist/site-tree-nav-island/state.js +10 -0
  155. package/dist/tag-helpers/index.d.ts +6 -13
  156. package/dist/tag-helpers/index.js +5 -23
  157. package/dist/tag-pages/index.d.ts +8 -21
  158. package/dist/tag-pages/index.js +14 -10
  159. package/dist/tags-audit.d.ts +16 -44
  160. package/dist/tags-audit.js +9 -172
  161. package/dist/theme/color-scheme-provider.d.ts +2 -3
  162. package/dist/theme/color-scheme-provider.js +2 -10
  163. package/dist/theme/index.d.ts +1 -4
  164. package/dist/theme/index.js +2 -30
  165. package/dist/theme/theme-pack-provider.d.ts +42 -0
  166. package/dist/theme/theme-pack-provider.js +75 -0
  167. package/dist/theme-cli/apply.d.ts +16 -0
  168. package/dist/theme-cli/apply.js +61 -0
  169. package/dist/theme-cli/config-io.d.ts +15 -0
  170. package/dist/theme-cli/config-io.js +51 -0
  171. package/dist/theme-cli/config-rewriter.d.ts +21 -0
  172. package/dist/theme-cli/config-rewriter.js +141 -0
  173. package/dist/theme-cli/config-scanner.d.ts +63 -0
  174. package/dist/theme-cli/config-scanner.js +288 -0
  175. package/dist/theme-cli/index.d.ts +7 -0
  176. package/dist/theme-cli/index.js +38 -0
  177. package/dist/theme-cli/list.d.ts +27 -0
  178. package/dist/theme-cli/list.js +64 -0
  179. package/dist/theme-cli/provenance.d.ts +17 -0
  180. package/dist/theme-cli/provenance.js +35 -0
  181. package/dist/theme-cli/registry.d.ts +14 -0
  182. package/dist/theme-cli/registry.js +13 -0
  183. package/dist/theme-pack-dialog/dialog-state.d.ts +25 -0
  184. package/dist/theme-pack-dialog/dialog-state.js +40 -0
  185. package/dist/theme-pack-dialog/index.d.ts +5 -0
  186. package/dist/theme-pack-dialog/index.js +152 -0
  187. package/dist/theme-pack-dialog/theme-pack-card.d.ts +25 -0
  188. package/dist/theme-pack-dialog/theme-pack-card.js +72 -0
  189. package/dist/theme-pack-switcher/index.d.ts +49 -0
  190. package/dist/theme-pack-switcher/index.js +205 -0
  191. package/dist/theme-pack-switcher/switcher-state.d.ts +56 -0
  192. package/dist/theme-pack-switcher/switcher-state.js +43 -0
  193. package/dist/theme-pack-switcher/theme-pack-sync.d.ts +85 -0
  194. package/dist/theme-pack-switcher/theme-pack-sync.js +121 -0
  195. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-400-latin.woff2 +0 -0
  196. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-700-latin.woff2 +0 -0
  197. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-400-latin.woff2 +0 -0
  198. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegible-italic-700-latin.woff2 +0 -0
  199. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-italic-latin.woff2 +0 -0
  200. package/dist/theme-packs/beacon/fonts/AtkinsonHyperlegibleMono-latin.woff2 +0 -0
  201. package/dist/theme-packs/beacon/fonts/OFL.txt +94 -0
  202. package/dist/theme-packs/beacon/meta.json +37 -0
  203. package/dist/theme-packs/beacon/pack.css +442 -0
  204. package/dist/theme-packs/broadsheet/fonts/CourierPrime-400-latin.woff2 +0 -0
  205. package/dist/theme-packs/broadsheet/fonts/CourierPrime-700-latin.woff2 +0 -0
  206. package/dist/theme-packs/broadsheet/fonts/OFL.txt +95 -0
  207. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-italic-latin.woff2 +0 -0
  208. package/dist/theme-packs/broadsheet/fonts/PlayfairDisplay-latin.woff2 +0 -0
  209. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-italic-latin.woff2 +0 -0
  210. package/dist/theme-packs/broadsheet/fonts/SourceSerif4-latin.woff2 +0 -0
  211. package/dist/theme-packs/broadsheet/meta.json +38 -0
  212. package/dist/theme-packs/broadsheet/pack.css +448 -0
  213. package/dist/theme-packs/brutalist/fonts/ArchivoBlack-latin.woff2 +0 -0
  214. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  215. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  216. package/dist/theme-packs/brutalist/fonts/IBMPlexMono-700-latin.woff2 +0 -0
  217. package/dist/theme-packs/brutalist/fonts/OFL.txt +95 -0
  218. package/dist/theme-packs/brutalist/fonts/SpaceGrotesk-latin.woff2 +0 -0
  219. package/dist/theme-packs/brutalist/meta.json +38 -0
  220. package/dist/theme-packs/brutalist/pack.css +546 -0
  221. package/dist/theme-packs/default/meta.json +37 -0
  222. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  223. package/dist/theme-packs/drift/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  224. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  225. package/dist/theme-packs/drift/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  226. package/dist/theme-packs/drift/fonts/IBMPlexSans-italic-latin.woff2 +0 -0
  227. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin-ext.woff2 +0 -0
  228. package/dist/theme-packs/drift/fonts/IBMPlexSans-latin.woff2 +0 -0
  229. package/dist/theme-packs/drift/fonts/OFL.txt +93 -0
  230. package/dist/theme-packs/drift/meta.json +37 -0
  231. package/dist/theme-packs/drift/pack.css +478 -0
  232. package/dist/theme-packs/fjord/fonts/Inter-latin-ext.woff2 +0 -0
  233. package/dist/theme-packs/fjord/fonts/Inter-latin.woff2 +0 -0
  234. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  235. package/dist/theme-packs/fjord/fonts/JetBrainsMono-latin.woff2 +0 -0
  236. package/dist/theme-packs/fjord/fonts/OFL.txt +94 -0
  237. package/dist/theme-packs/fjord/meta.json +37 -0
  238. package/dist/theme-packs/fjord/pack.css +375 -0
  239. package/dist/theme-packs/foundry/fonts/Inter-latin-ext.woff2 +0 -0
  240. package/dist/theme-packs/foundry/fonts/Inter-latin.woff2 +0 -0
  241. package/dist/theme-packs/foundry/fonts/OFL.txt +93 -0
  242. package/dist/theme-packs/foundry/meta.json +37 -0
  243. package/dist/theme-packs/foundry/pack.css +202 -0
  244. package/dist/theme-packs/futura-editorial/fonts/Jost-latin.woff2 +0 -0
  245. package/dist/theme-packs/futura-editorial/fonts/NotoSans-italic-latin.woff2 +0 -0
  246. package/dist/theme-packs/futura-editorial/fonts/NotoSans-latin.woff2 +0 -0
  247. package/dist/theme-packs/futura-editorial/fonts/OFL.txt +95 -0
  248. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-400-latin.woff2 +0 -0
  249. package/dist/theme-packs/futura-editorial/fonts/SpaceMono-700-latin.woff2 +0 -0
  250. package/dist/theme-packs/futura-editorial/meta.json +38 -0
  251. package/dist/theme-packs/futura-editorial/pack.css +313 -0
  252. package/dist/theme-packs/hearth/fonts/Fraunces-italic-latin.woff2 +0 -0
  253. package/dist/theme-packs/hearth/fonts/Fraunces-latin.woff2 +0 -0
  254. package/dist/theme-packs/hearth/fonts/Nunito-latin.woff2 +0 -0
  255. package/dist/theme-packs/hearth/fonts/OFL.txt +95 -0
  256. package/dist/theme-packs/hearth/fonts/SplineSansMono-latin.woff2 +0 -0
  257. package/dist/theme-packs/hearth/meta.json +38 -0
  258. package/dist/theme-packs/hearth/pack.css +385 -0
  259. package/dist/theme-packs/hollow/fonts/OFL.txt +94 -0
  260. package/dist/theme-packs/hollow/fonts/SpaceGrotesk-latin.woff2 +0 -0
  261. package/dist/theme-packs/hollow/fonts/SpaceMono-400-italic-latin.woff2 +0 -0
  262. package/dist/theme-packs/hollow/fonts/SpaceMono-400-latin.woff2 +0 -0
  263. package/dist/theme-packs/hollow/fonts/SpaceMono-700-latin.woff2 +0 -0
  264. package/dist/theme-packs/hollow/meta.json +37 -0
  265. package/dist/theme-packs/hollow/pack.css +428 -0
  266. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext-italic.woff2 +0 -0
  267. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-ext.woff2 +0 -0
  268. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin-italic.woff2 +0 -0
  269. package/dist/theme-packs/ledger/fonts/CrimsonPro-latin.woff2 +0 -0
  270. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  271. package/dist/theme-packs/ledger/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  272. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  273. package/dist/theme-packs/ledger/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  274. package/dist/theme-packs/ledger/fonts/OFL.txt +94 -0
  275. package/dist/theme-packs/ledger/meta.json +37 -0
  276. package/dist/theme-packs/ledger/pack.css +463 -0
  277. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin-ext.woff2 +0 -0
  278. package/dist/theme-packs/manuscript/fonts/CourierPrime-400-latin.woff2 +0 -0
  279. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin-ext.woff2 +0 -0
  280. package/dist/theme-packs/manuscript/fonts/CourierPrime-700-latin.woff2 +0 -0
  281. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin-italic.woff2 +0 -0
  282. package/dist/theme-packs/manuscript/fonts/EBGaramond-latin.woff2 +0 -0
  283. package/dist/theme-packs/manuscript/fonts/OFL.txt +94 -0
  284. package/dist/theme-packs/manuscript/meta.json +37 -0
  285. package/dist/theme-packs/manuscript/pack.css +376 -0
  286. package/dist/theme-packs/matcha/fonts/MPLUS1Code-latin.woff2 +0 -0
  287. package/dist/theme-packs/matcha/fonts/OFL.txt +95 -0
  288. package/dist/theme-packs/matcha/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  289. package/dist/theme-packs/matcha/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  290. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  291. package/dist/theme-packs/matcha/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  292. package/dist/theme-packs/matcha/meta.json +38 -0
  293. package/dist/theme-packs/matcha/pack.css +409 -0
  294. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  295. package/dist/theme-packs/nocturne/fonts/CormorantGaramond-latin.woff2 +0 -0
  296. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  297. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  298. package/dist/theme-packs/nocturne/fonts/IBMPlexMono-italic-latin.woff2 +0 -0
  299. package/dist/theme-packs/nocturne/fonts/Manrope-latin.woff2 +0 -0
  300. package/dist/theme-packs/nocturne/fonts/OFL.txt +95 -0
  301. package/dist/theme-packs/nocturne/meta.json +38 -0
  302. package/dist/theme-packs/nocturne/pack.css +502 -0
  303. package/dist/theme-packs/observatory/fonts/JosefinSans-latin.woff2 +0 -0
  304. package/dist/theme-packs/observatory/fonts/Jost-italic-latin.woff2 +0 -0
  305. package/dist/theme-packs/observatory/fonts/Jost-latin.woff2 +0 -0
  306. package/dist/theme-packs/observatory/fonts/OFL.txt +95 -0
  307. package/dist/theme-packs/observatory/fonts/SpaceMono-400-latin.woff2 +0 -0
  308. package/dist/theme-packs/observatory/fonts/SpaceMono-700-latin.woff2 +0 -0
  309. package/dist/theme-packs/observatory/fonts/SpaceMono-italic-latin.woff2 +0 -0
  310. package/dist/theme-packs/observatory/meta.json +38 -0
  311. package/dist/theme-packs/observatory/pack.css +728 -0
  312. package/dist/theme-packs/onyx/fonts/CormorantGaramond-italic-latin.woff2 +0 -0
  313. package/dist/theme-packs/onyx/fonts/CormorantGaramond-latin.woff2 +0 -0
  314. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  315. package/dist/theme-packs/onyx/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  316. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  317. package/dist/theme-packs/onyx/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  318. package/dist/theme-packs/onyx/fonts/Jost-latin.woff2 +0 -0
  319. package/dist/theme-packs/onyx/fonts/OFL.txt +95 -0
  320. package/dist/theme-packs/onyx/meta.json +38 -0
  321. package/dist/theme-packs/onyx/pack.css +497 -0
  322. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin-ext.woff2 +0 -0
  323. package/dist/theme-packs/phosphor/fonts/JetBrainsMono-latin.woff2 +0 -0
  324. package/dist/theme-packs/phosphor/fonts/OFL.txt +94 -0
  325. package/dist/theme-packs/phosphor/fonts/VT323-latin-ext.woff2 +0 -0
  326. package/dist/theme-packs/phosphor/fonts/VT323-latin.woff2 +0 -0
  327. package/dist/theme-packs/phosphor/meta.json +38 -0
  328. package/dist/theme-packs/phosphor/pack.css +493 -0
  329. package/dist/theme-packs/solar/fonts/OFL.txt +94 -0
  330. package/dist/theme-packs/solar/fonts/SourceCodePro-italic-latin.woff2 +0 -0
  331. package/dist/theme-packs/solar/fonts/SourceCodePro-latin.woff2 +0 -0
  332. package/dist/theme-packs/solar/fonts/SourceSans3-italic-latin.woff2 +0 -0
  333. package/dist/theme-packs/solar/fonts/SourceSans3-latin.woff2 +0 -0
  334. package/dist/theme-packs/solar/meta.json +37 -0
  335. package/dist/theme-packs/solar/pack.css +380 -0
  336. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  337. package/dist/theme-packs/sumi/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  338. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin-ext.woff2 +0 -0
  339. package/dist/theme-packs/sumi/fonts/IBMPlexMono-500-latin.woff2 +0 -0
  340. package/dist/theme-packs/sumi/fonts/OFL.txt +95 -0
  341. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-600-latin.woff2 +0 -0
  342. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-700-latin.woff2 +0 -0
  343. package/dist/theme-packs/sumi/fonts/ShipporiMinchoB1-800-latin.woff2 +0 -0
  344. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  345. package/dist/theme-packs/sumi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  346. package/dist/theme-packs/sumi/meta.json +38 -0
  347. package/dist/theme-packs/sumi/pack.css +502 -0
  348. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin-ext.woff2 +0 -0
  349. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-400-latin.woff2 +0 -0
  350. package/dist/theme-packs/swissgrid/fonts/IBMPlexMono-600-latin.woff2 +0 -0
  351. package/dist/theme-packs/swissgrid/fonts/Inter-latin-ext.woff2 +0 -0
  352. package/dist/theme-packs/swissgrid/fonts/Inter-latin.woff2 +0 -0
  353. package/dist/theme-packs/swissgrid/fonts/InterTight-latin.woff2 +0 -0
  354. package/dist/theme-packs/swissgrid/fonts/OFL.txt +95 -0
  355. package/dist/theme-packs/swissgrid/meta.json +38 -0
  356. package/dist/theme-packs/swissgrid/pack.css +518 -0
  357. package/dist/theme-packs/washi/fonts/MPlus1Code-400-latin.woff2 +0 -0
  358. package/dist/theme-packs/washi/fonts/MPlus1Code-500-latin.woff2 +0 -0
  359. package/dist/theme-packs/washi/fonts/OFL.txt +95 -0
  360. package/dist/theme-packs/washi/fonts/ShipporiMincho-500-latin.woff2 +0 -0
  361. package/dist/theme-packs/washi/fonts/ShipporiMincho-600-latin.woff2 +0 -0
  362. package/dist/theme-packs/washi/fonts/ShipporiMincho-700-latin.woff2 +0 -0
  363. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-400-latin.woff2 +0 -0
  364. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-500-latin.woff2 +0 -0
  365. package/dist/theme-packs/washi/fonts/ZenKakuGothicNew-700-latin.woff2 +0 -0
  366. package/dist/theme-packs/washi/meta.json +38 -0
  367. package/dist/theme-packs/washi/pack.css +479 -0
  368. package/dist/theme-packs-registry/index.d.ts +5 -0
  369. package/dist/theme-packs-registry/index.js +30 -0
  370. package/dist/theme-packs-registry/load-registry.d.ts +23 -0
  371. package/dist/theme-packs-registry/load-registry.js +64 -0
  372. package/dist/theme-packs-registry/meta-schema.d.ts +70 -0
  373. package/dist/theme-packs-registry/meta-schema.js +38 -0
  374. package/dist/theme-packs-registry/resolve-enabled-packs.d.ts +25 -0
  375. package/dist/theme-packs-registry/resolve-enabled-packs.js +43 -0
  376. package/dist/theme-packs-registry/token-manifest.d.ts +19 -0
  377. package/dist/theme-packs-registry/token-manifest.js +57 -0
  378. package/dist/theme-packs-registry/validator.d.ts +35 -0
  379. package/dist/theme-packs-registry/validator.js +284 -0
  380. package/dist/theme-toggle/color-scheme-sync.d.ts +2 -4
  381. package/dist/theme.css +319 -0
  382. package/dist/versions-page/index.d.ts +2 -2
  383. package/dist/versions-page/index.js +8 -8
  384. package/dist/z-index-defaults/index.d.ts +45 -0
  385. package/dist/z-index-defaults/index.js +34 -0
  386. package/eject/breadcrumb/breadcrumb.tsx +4 -4
  387. package/eject/breadcrumb/find-path.ts +2 -2
  388. package/eject/breadcrumb/index.ts +1 -1
  389. package/eject/breadcrumb/types.ts +0 -6
  390. package/eject/code-group/index.tsx +2 -2
  391. package/eject/doc-history/index.tsx +1 -1
  392. package/eject/doc-pager/index.tsx +1 -1
  393. package/eject/footer/footer.tsx +1 -0
  394. package/eject/header/header.tsx +86 -21
  395. package/eject/header/index.ts +3 -0
  396. package/eject/header/types.ts +39 -1
  397. package/eject/site-tree-nav-island/index.tsx +15 -3
  398. package/eject/site-tree-nav-island/state.ts +9 -0
  399. package/eject/theme-toggle/color-scheme-sync.ts +2 -4
  400. package/package.json +82 -29
  401. package/routes-src/404.tsx +4 -1
  402. package/routes-src/_chrome.tsx +31 -8
  403. package/routes-src/_context.ts +4 -0
  404. package/routes-src/_docs-helpers.ts +9 -29
  405. package/routes-src/_virtual.d.ts +38 -2
  406. package/tsconfig.base.json +29 -0
  407. package/virtual-modules.d.ts +83 -0
  408. package/zfb-config-shim.d.ts +210 -0
  409. package/dist/integrations/llms-txt/index.d.ts +0 -33
  410. package/dist/theme/color-tweak-export-modal.d.ts +0 -16
  411. package/dist/theme/color-tweak-export-modal.js +0 -138
  412. package/dist/theme/design-token-serde.d.ts +0 -183
  413. package/dist/theme/design-token-serde.js +0 -346
  414. package/dist/theme/design-token-types.d.ts +0 -13
  415. package/dist/theme/design-token-types.js +0 -6
  416. package/dist/theme/iframe-bridge.d.ts +0 -42
  417. package/dist/theme/iframe-bridge.js +0 -72
  418. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.d.ts +0 -0
  419. /package/dist/{integrations → plugins/internal}/claude-resources/escape-for-mdx.js +0 -0
  420. /package/dist/{integrations → plugins/internal}/claude-resources/generate.d.ts +0 -0
  421. /package/dist/{integrations → plugins/internal}/claude-resources/generate.js +0 -0
  422. /package/dist/{integrations → plugins/internal}/doc-history/pre-build.js +0 -0
  423. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.d.ts +0 -0
  424. /package/dist/{integrations → plugins/internal}/llms-txt/dev-middleware.js +0 -0
  425. /package/dist/{integrations → plugins/internal}/llms-txt/emit.d.ts +0 -0
  426. /package/dist/{integrations → plugins/internal}/llms-txt/emit.js +0 -0
  427. /package/dist/{integrations → plugins/internal}/llms-txt/generate.d.ts +0 -0
  428. /package/dist/{integrations → plugins/internal}/llms-txt/generate.js +0 -0
  429. /package/dist/{integrations → plugins/internal}/llms-txt/index.js +0 -0
  430. /package/dist/{integrations → plugins/internal}/llms-txt/types.js +0 -0
  431. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.d.ts +0 -0
  432. /package/dist/{integrations → plugins/internal}/search-index/build-emitter.js +0 -0
  433. /package/dist/{integrations → plugins/internal}/search-index/collect.d.ts +0 -0
  434. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.d.ts +0 -0
  435. /package/dist/{integrations → plugins/internal}/search-index/dev-middleware.js +0 -0
  436. /package/dist/{integrations → plugins/internal}/search-index/index.d.ts +0 -0
  437. /package/dist/{integrations → plugins/internal}/search-index/index.js +0 -0
  438. /package/dist/{integrations → plugins/internal}/search-index/types.d.ts +0 -0
  439. /package/dist/{integrations → plugins/internal}/search-index/types.js +0 -0
@@ -0,0 +1,38 @@
1
+ import { z } from "zod";
2
+ const THEME_PACK_SLUG_RE = /^[a-z0-9][a-z0-9-]*$/;
3
+ const DEFAULT_THEME_PACK_SLUG = "default";
4
+ const SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
5
+ const themePackSwatchesSchema = z.object({
6
+ bg: z.string().min(1),
7
+ fg: z.string().min(1),
8
+ accent: z.string().min(1),
9
+ syntax: z.object({
10
+ keyword: z.string().min(1),
11
+ string: z.string().min(1),
12
+ comment: z.string().min(1),
13
+ callable: z.string().min(1)
14
+ })
15
+ });
16
+ const themePackMetaSchema = z.object({
17
+ schemaVersion: z.literal(1),
18
+ slug: z.string().regex(THEME_PACK_SLUG_RE, "must match [a-z0-9][a-z0-9-]*"),
19
+ name: z.string().min(1),
20
+ description: z.string().min(1),
21
+ mode: z.enum(["light", "dark"]),
22
+ version: z.string().regex(SEMVER_RE, "must be a semver string, e.g. 1.0.0"),
23
+ fonts: z.object({
24
+ sans: z.string().min(1),
25
+ mono: z.string().min(1),
26
+ display: z.string().min(1).optional(),
27
+ loaded: z.array(z.string().min(1))
28
+ }),
29
+ preview: z.object({
30
+ light: themePackSwatchesSchema,
31
+ dark: themePackSwatchesSchema
32
+ })
33
+ });
34
+ export {
35
+ DEFAULT_THEME_PACK_SLUG,
36
+ THEME_PACK_SLUG_RE,
37
+ themePackMetaSchema
38
+ };
@@ -0,0 +1,25 @@
1
+ import type { ThemePackRegistry } from "./load-registry.js";
2
+ /** The subset of settings this resolver reads. */
3
+ export interface ResolveEnabledPacksSettings {
4
+ /** Active pack slug — must end up a member of the resolved list. */
5
+ themePack?: string;
6
+ /** Explicit enabled-pack order, or `undefined` for the canonical default
7
+ * order (`"default"` first, then the rest alphabetically). */
8
+ themePacks?: string[];
9
+ }
10
+ /**
11
+ * Resolve the ENABLED, ORDERED subset of `registry` per `settings.themePacks`
12
+ * / `settings.themePack` (Decision 7):
13
+ *
14
+ * - `themePacks` omitted → every bundled pack, `"default"` first, then the
15
+ * rest in canonical (alphabetical-by-slug) order.
16
+ * - `themePacks` an explicit array → authoritative: may omit `"default"`,
17
+ * reorder freely. Duplicate or unknown slugs throw loudly.
18
+ * - `themePack` (the active slug, default `"default"`) must be a member of
19
+ * the resolved list — an unknown/excluded active slug throws loudly,
20
+ * naming the bad slug and the available ones.
21
+ *
22
+ * Pure — throws synchronously on misconfiguration; never returns a partial
23
+ * or silently-corrected result.
24
+ */
25
+ export declare function resolveEnabledPacks(registry: ThemePackRegistry, settings: ResolveEnabledPacksSettings): ThemePackRegistry;
@@ -0,0 +1,43 @@
1
+ import { DEFAULT_THEME_PACK_SLUG } from "./meta-schema.js";
2
+ function resolveEnabledPacks(registry, settings) {
3
+ const bySlug = new Map(registry.map((entry) => [entry.slug, entry]));
4
+ const availableSlugs = registry.map((e) => e.slug);
5
+ let orderedSlugs;
6
+ if (settings.themePacks === void 0) {
7
+ const hasDefault = bySlug.has(DEFAULT_THEME_PACK_SLUG);
8
+ const rest = availableSlugs.filter((s) => s !== DEFAULT_THEME_PACK_SLUG).sort();
9
+ orderedSlugs = hasDefault ? [DEFAULT_THEME_PACK_SLUG, ...rest] : rest;
10
+ } else {
11
+ const requested = settings.themePacks;
12
+ const seen = /* @__PURE__ */ new Set();
13
+ const duplicates = [];
14
+ const unknown = [];
15
+ for (const slug of requested) {
16
+ if (seen.has(slug)) duplicates.push(slug);
17
+ seen.add(slug);
18
+ if (!bySlug.has(slug)) unknown.push(slug);
19
+ }
20
+ if (duplicates.length > 0) {
21
+ throw new Error(
22
+ `zudo-doc: settings.themePacks contains duplicate slug(s): ${[...new Set(duplicates)].join(", ")}.`
23
+ );
24
+ }
25
+ if (unknown.length > 0) {
26
+ throw new Error(
27
+ `zudo-doc: settings.themePacks references unknown theme pack slug(s): ${unknown.join(", ")}. Available packs: ${availableSlugs.join(", ") || "(none)"}.`
28
+ );
29
+ }
30
+ orderedSlugs = [...requested];
31
+ }
32
+ const enabled = orderedSlugs.map((slug) => bySlug.get(slug));
33
+ const activeSlug = settings.themePack ?? DEFAULT_THEME_PACK_SLUG;
34
+ if (!enabled.some((e) => e.slug === activeSlug)) {
35
+ throw new Error(
36
+ `zudo-doc: settings.themePack "${activeSlug}" is not one of the enabled theme packs. Enabled packs: ${enabled.map((e) => e.slug).join(", ") || "(none)"}.`
37
+ );
38
+ }
39
+ return enabled;
40
+ }
41
+ export {
42
+ resolveEnabledPacks
43
+ };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The full closed set of custom-property names a `pack.css` may declare —
3
+ * every `--zd-*` semantic + syntax role, every `--zdc-*` component token,
4
+ * the allowed `--font-*` family tokens, and the `--zfb-hi-*` bridge. Anything
5
+ * else (a typo'd `--zd-syntx-keyword`, or a net-new invented property) fails
6
+ * the validator's known-token-name check.
7
+ */
8
+ export declare const KNOWN_THEME_PACK_TOKEN_NAMES: ReadonlySet<string>;
9
+ /**
10
+ * Commercial type-face names that may never appear in a pack's `@font-face`
11
+ * `src`/`local()` list or any `font-family` stack (ADR Decision 5 — a
12
+ * commercial face is never load-bearing; the pack's actual loaded face is
13
+ * always a designated OFL substitute, e.g. Jost for Futura). Case-insensitive
14
+ * substring match.
15
+ */
16
+ export declare const COMMERCIAL_FONT_DENYLIST: readonly string[];
17
+ /** Soft budget for total pack payload (css + font bytes) — Decision 6.7 /
18
+ * Decision 5 "Budget (soft)". Exceeding it is a WARNING, not an error. */
19
+ export declare const THEME_PACK_SOFT_BUDGET_BYTES: number;
@@ -0,0 +1,57 @@
1
+ import { SEMANTIC_CSS_NAMES, SYNTAX_CSS_NAMES } from "../color-scheme-utils.js";
2
+ import { COMPONENT_TOKENS } from "../config/component-tokens.js";
3
+ const ZD_BASE_ROLE_NAMES = [
4
+ "--zd-bg",
5
+ "--zd-fg",
6
+ "--zd-selection-bg",
7
+ "--zd-selection-fg"
8
+ ];
9
+ const FONT_TOKEN_NAMES = ["--font-sans", "--font-mono", "--font-display"];
10
+ const ZFB_HI_BRIDGE_NAMES = [
11
+ "--zfb-hi-fg",
12
+ "--zfb-hi-bg",
13
+ "--zfb-hi-esc",
14
+ "--zfb-hi-op",
15
+ "--zfb-hi-com",
16
+ "--zfb-hi-str",
17
+ "--zfb-hi-num",
18
+ "--zfb-hi-const",
19
+ "--zfb-hi-kw",
20
+ "--zfb-hi-fn",
21
+ "--zfb-hi-ty",
22
+ "--zfb-hi-ns",
23
+ "--zfb-hi-prop",
24
+ "--zfb-hi-var",
25
+ "--zfb-hi-tag",
26
+ "--zfb-hi-attr",
27
+ "--zfb-hi-punct",
28
+ "--zfb-hi-ins",
29
+ "--zfb-hi-ins-bg",
30
+ "--zfb-hi-del",
31
+ "--zfb-hi-del-bg",
32
+ "--zfb-hi-hd"
33
+ ];
34
+ const KNOWN_THEME_PACK_TOKEN_NAMES = /* @__PURE__ */ new Set([
35
+ ...ZD_BASE_ROLE_NAMES,
36
+ ...Object.values(SEMANTIC_CSS_NAMES),
37
+ ...Object.values(SYNTAX_CSS_NAMES),
38
+ ...COMPONENT_TOKENS.map((t) => t.cssVar),
39
+ ...FONT_TOKEN_NAMES,
40
+ ...ZFB_HI_BRIDGE_NAMES
41
+ ]);
42
+ const COMMERCIAL_FONT_DENYLIST = [
43
+ "Futura",
44
+ "Helvetica Neue",
45
+ "Helvetica",
46
+ "Avenir",
47
+ "Gill Sans",
48
+ "Univers",
49
+ "Frutiger",
50
+ "Garamond Premier"
51
+ ];
52
+ const THEME_PACK_SOFT_BUDGET_BYTES = 250 * 1024;
53
+ export {
54
+ COMMERCIAL_FONT_DENYLIST,
55
+ KNOWN_THEME_PACK_TOKEN_NAMES,
56
+ THEME_PACK_SOFT_BUDGET_BYTES
57
+ };
@@ -0,0 +1,35 @@
1
+ import { type ThemePackMeta } from "./meta-schema.js";
2
+ export type ThemePackValidationSeverity = "error" | "warning";
3
+ export interface ThemePackValidationIssue {
4
+ /** Short machine-readable rule id, e.g. `"scoping"` or `"known-token-names"`. */
5
+ rule: string;
6
+ message: string;
7
+ severity: ThemePackValidationSeverity;
8
+ }
9
+ export interface ThemePackValidationInput {
10
+ /** The pack's directory name (used for slug/dir-name parity). */
11
+ dirName: string;
12
+ /** `JSON.parse`-d `meta.json` content, pre-schema-validation. */
13
+ metaRaw: unknown;
14
+ /** `pack.css` text content, or `null` when the file is absent. */
15
+ cssContent: string | null;
16
+ /** Basenames of every file inside the pack's `fonts/` directory (`[]` when
17
+ * the directory is absent or empty). */
18
+ fontFiles: string[];
19
+ /** Optional total payload size (css + font bytes) for the soft budget
20
+ * check. Omit to skip that check entirely. */
21
+ totalPayloadBytes?: number;
22
+ }
23
+ export interface ThemePackValidationResult {
24
+ /** `true` iff no issue has `severity: "error"`. */
25
+ valid: boolean;
26
+ issues: ThemePackValidationIssue[];
27
+ /** The schema-parsed meta, present iff the schema check passed. */
28
+ meta?: ThemePackMeta;
29
+ }
30
+ /**
31
+ * Validate a single theme pack against every Decision 6.7 authoring-
32
+ * convention rule. Filesystem-free — pass in the raw content the caller
33
+ * already read from disk (or, in a test, constructed directly).
34
+ */
35
+ export declare function validateThemePack(input: ThemePackValidationInput): ThemePackValidationResult;
@@ -0,0 +1,284 @@
1
+ import {
2
+ themePackMetaSchema,
3
+ THEME_PACK_SLUG_RE,
4
+ DEFAULT_THEME_PACK_SLUG
5
+ } from "./meta-schema.js";
6
+ import {
7
+ KNOWN_THEME_PACK_TOKEN_NAMES,
8
+ COMMERCIAL_FONT_DENYLIST,
9
+ THEME_PACK_SOFT_BUDGET_BYTES
10
+ } from "./token-manifest.js";
11
+ function stripComments(css) {
12
+ return css.replace(/\/\*[\s\S]*?\*\//g, "");
13
+ }
14
+ function parseTopLevelRules(css) {
15
+ const text = stripComments(css);
16
+ const rules = [];
17
+ const n = text.length;
18
+ let i = 0;
19
+ while (i < n) {
20
+ const braceIdx = text.indexOf("{", i);
21
+ if (braceIdx === -1) break;
22
+ const preludeRaw = text.slice(i, braceIdx).replace(/@[a-zA-Z-]+[^{;]*;/g, "");
23
+ const prelude = preludeRaw.trim();
24
+ let depth = 1;
25
+ let j = braceIdx + 1;
26
+ while (j < n && depth > 0) {
27
+ const ch = text[j];
28
+ if (ch === "{") depth++;
29
+ else if (ch === "}") depth--;
30
+ j++;
31
+ }
32
+ const body = text.slice(braceIdx + 1, Math.max(braceIdx + 1, j - 1));
33
+ if (prelude.length > 0) rules.push({ prelude, body });
34
+ i = j;
35
+ }
36
+ return rules;
37
+ }
38
+ function isFontFaceRule(rule) {
39
+ return /^@font-face\b/i.test(rule.prelude);
40
+ }
41
+ function extractFontFaceFamilies(cssContent) {
42
+ const families = [];
43
+ for (const rule of parseTopLevelRules(cssContent)) {
44
+ if (!isFontFaceRule(rule)) continue;
45
+ const m = rule.body.match(/font-family\s*:\s*([^;]+);/i);
46
+ if (!m) continue;
47
+ const raw = m[1].trim();
48
+ families.push(raw.replace(/^["']|["']$/g, ""));
49
+ }
50
+ return families;
51
+ }
52
+ function checkSlugAndDirParity(dirName, meta, issues) {
53
+ if (!THEME_PACK_SLUG_RE.test(dirName)) {
54
+ issues.push({
55
+ rule: "slug-dir-parity",
56
+ severity: "error",
57
+ message: `directory name "${dirName}" does not match the required slug pattern [a-z0-9][a-z0-9-]*`
58
+ });
59
+ }
60
+ if (meta && meta.slug !== dirName) {
61
+ issues.push({
62
+ rule: "slug-dir-parity",
63
+ severity: "error",
64
+ message: `meta.json "slug" ("${meta.slug}") must equal the directory name ("${dirName}")`
65
+ });
66
+ }
67
+ }
68
+ function checkCssPresence(dirName, cssContent, issues) {
69
+ if (dirName === DEFAULT_THEME_PACK_SLUG) {
70
+ if (cssContent !== null) {
71
+ issues.push({
72
+ rule: "css-presence",
73
+ severity: "error",
74
+ message: `the reserved "${DEFAULT_THEME_PACK_SLUG}" pack must NOT ship pack.css (it is the no-op stock look)`
75
+ });
76
+ }
77
+ return;
78
+ }
79
+ if (cssContent === null || cssContent.trim().length === 0) {
80
+ issues.push({
81
+ rule: "css-presence",
82
+ severity: "error",
83
+ message: `pack "${dirName}" must ship a non-empty pack.css`
84
+ });
85
+ }
86
+ }
87
+ function checkScoping(slug, cssContent, issues) {
88
+ const prefix = `html[data-theme-pack="${slug}"]`;
89
+ for (const rule of parseTopLevelRules(cssContent)) {
90
+ if (isFontFaceRule(rule)) continue;
91
+ for (const rawBranch of rule.prelude.split(",")) {
92
+ const branch = rawBranch.trim();
93
+ if (branch.length === 0) continue;
94
+ if (!branch.startsWith(prefix)) {
95
+ issues.push({
96
+ rule: "scoping",
97
+ severity: "error",
98
+ message: `selector "${branch}" is not scoped under ${prefix}`
99
+ });
100
+ }
101
+ }
102
+ }
103
+ }
104
+ function checkKnownTokenNames(cssContent, issues) {
105
+ const re = /--([a-zA-Z0-9-]+)\s*:/g;
106
+ const text = stripComments(cssContent);
107
+ const reported = /* @__PURE__ */ new Set();
108
+ let m;
109
+ while ((m = re.exec(text)) !== null) {
110
+ const name = `--${m[1]}`;
111
+ if (reported.has(name) || KNOWN_THEME_PACK_TOKEN_NAMES.has(name)) continue;
112
+ reported.add(name);
113
+ issues.push({
114
+ rule: "known-token-names",
115
+ severity: "error",
116
+ message: `unknown custom property "${name}" \u2014 not part of the --zd-*/--zdc-*/--font-*/--zfb-hi-* token contract (possible typo)`
117
+ });
118
+ }
119
+ }
120
+ function checkImportantAllowlist(cssContent, issues) {
121
+ const text = stripComments(cssContent);
122
+ const re = /([a-zA-Z-]+)\s*:\s*[^;{}]*!important[^;{}]*;/g;
123
+ let m;
124
+ while ((m = re.exec(text)) !== null) {
125
+ const prop = m[1].toLowerCase();
126
+ if (prop !== "border-image") {
127
+ issues.push({
128
+ rule: "important-allowlist",
129
+ severity: "error",
130
+ message: `"!important" is only allowed on a "border-image" declaration (the h2\u2013h4 heading-rule gradient carve-out, Decision 6.6) \u2014 found on "${prop}"`
131
+ });
132
+ }
133
+ }
134
+ }
135
+ function checkNoColorScheme(cssContent, issues) {
136
+ const text = stripComments(cssContent);
137
+ if (/(^|[;{}\s])color-scheme\s*:/.test(text)) {
138
+ issues.push({
139
+ rule: "no-color-scheme",
140
+ severity: "error",
141
+ message: `pack.css must not declare "color-scheme:" \u2014 mode is exclusively owned by the light/dark toggle machinery`
142
+ });
143
+ }
144
+ }
145
+ function checkNoDataThemeSelector(cssContent, issues) {
146
+ const text = stripComments(cssContent);
147
+ if (/\[data-theme(?:=|\])/.test(text)) {
148
+ issues.push({
149
+ rule: "no-data-theme-selector",
150
+ severity: "error",
151
+ message: `pack.css must not select on "[data-theme]" \u2014 that attribute is owned by the light/dark mode toggle, not theme packs`
152
+ });
153
+ }
154
+ }
155
+ function checkFontFaceParity(cssContent, meta, issues) {
156
+ const declaredFamilies = new Set(cssContent ? extractFontFaceFamilies(cssContent) : []);
157
+ const loadedFamilies = new Set(meta.fonts.loaded);
158
+ for (const loaded of loadedFamilies) {
159
+ if (!declaredFamilies.has(loaded)) {
160
+ issues.push({
161
+ rule: "font-face-parity",
162
+ severity: "error",
163
+ message: `fonts.loaded lists "${loaded}" but pack.css has no matching @font-face`
164
+ });
165
+ }
166
+ }
167
+ for (const declared of declaredFamilies) {
168
+ if (!loadedFamilies.has(declared)) {
169
+ issues.push({
170
+ rule: "font-face-parity",
171
+ severity: "error",
172
+ message: `pack.css declares @font-face for "${declared}" but fonts.loaded does not list it`
173
+ });
174
+ }
175
+ }
176
+ }
177
+ function isPlainColorValue(value) {
178
+ const v = value.trim();
179
+ if (/var\(|light-dark\(/i.test(v)) return false;
180
+ if (/^#[0-9a-f]{3,8}$/i.test(v)) return true;
181
+ if (/^(oklch|oklab|rgb|rgba|hsl|hsla|lab|lch|color)\(/i.test(v)) return true;
182
+ if (/^[a-z]+$/i.test(v)) return true;
183
+ return false;
184
+ }
185
+ function checkPreviewSwatches(meta, issues) {
186
+ for (const mode of ["light", "dark"]) {
187
+ const sw = meta.preview[mode];
188
+ const entries = [
189
+ ["bg", sw.bg],
190
+ ["fg", sw.fg],
191
+ ["accent", sw.accent],
192
+ ["syntax.keyword", sw.syntax.keyword],
193
+ ["syntax.string", sw.syntax.string],
194
+ ["syntax.comment", sw.syntax.comment],
195
+ ["syntax.callable", sw.syntax.callable]
196
+ ];
197
+ for (const [key, value] of entries) {
198
+ if (!isPlainColorValue(value)) {
199
+ issues.push({
200
+ rule: "preview-swatch-color",
201
+ severity: "error",
202
+ message: `preview.${mode}.${key} ("${value}") is not a plain resolved CSS color \u2014 var()/light-dark() are not allowed`
203
+ });
204
+ }
205
+ }
206
+ }
207
+ }
208
+ function checkCommercialDenylist(cssContent, meta, issues) {
209
+ const scannedCss = (cssContent ?? "").replace(/\[data-theme-pack="[^"]*"\]/g, "");
210
+ const haystack = [
211
+ scannedCss,
212
+ meta.fonts.sans,
213
+ meta.fonts.mono,
214
+ meta.fonts.display ?? "",
215
+ ...meta.fonts.loaded
216
+ ].join("\n").toLowerCase();
217
+ for (const denied of COMMERCIAL_FONT_DENYLIST) {
218
+ if (haystack.includes(denied.toLowerCase())) {
219
+ issues.push({
220
+ rule: "commercial-font-denylist",
221
+ severity: "error",
222
+ message: `commercial typeface "${denied}" must not appear in pack.css or meta.json fonts \u2014 ship a self-hosted OFL substitute instead`
223
+ });
224
+ }
225
+ }
226
+ }
227
+ function checkOflPresence(fontFiles, issues) {
228
+ const hasFontBinary = fontFiles.some((f) => /\.(woff2?|ttf|otf)$/i.test(f));
229
+ const hasOfl = fontFiles.some((f) => f.toUpperCase() === "OFL.TXT");
230
+ if (hasFontBinary && !hasOfl) {
231
+ issues.push({
232
+ rule: "ofl-required",
233
+ severity: "error",
234
+ message: `fonts/ ships font binaries but no OFL.txt license file (OFL redistribution requirement)`
235
+ });
236
+ }
237
+ }
238
+ function checkPayloadBudget(totalPayloadBytes, issues) {
239
+ if (typeof totalPayloadBytes === "number" && totalPayloadBytes > THEME_PACK_SOFT_BUDGET_BYTES) {
240
+ issues.push({
241
+ rule: "payload-budget",
242
+ severity: "warning",
243
+ message: `total pack payload (~${Math.round(totalPayloadBytes / 1024)} KB) exceeds the ~250 KB soft budget`
244
+ });
245
+ }
246
+ }
247
+ function validateThemePack(input) {
248
+ const issues = [];
249
+ const metaParseResult = themePackMetaSchema.safeParse(input.metaRaw);
250
+ let meta;
251
+ if (!metaParseResult.success) {
252
+ for (const issue of metaParseResult.error.issues) {
253
+ const path = issue.path.length > 0 ? issue.path.join(".") : "(root)";
254
+ issues.push({
255
+ rule: "meta-schema",
256
+ severity: "error",
257
+ message: `meta.json "${path}": ${issue.message}`
258
+ });
259
+ }
260
+ } else {
261
+ meta = metaParseResult.data;
262
+ }
263
+ checkSlugAndDirParity(input.dirName, meta, issues);
264
+ checkCssPresence(input.dirName, input.cssContent, issues);
265
+ if (input.cssContent) {
266
+ checkScoping(input.dirName, input.cssContent, issues);
267
+ checkKnownTokenNames(input.cssContent, issues);
268
+ checkImportantAllowlist(input.cssContent, issues);
269
+ checkNoColorScheme(input.cssContent, issues);
270
+ checkNoDataThemeSelector(input.cssContent, issues);
271
+ }
272
+ if (meta) {
273
+ checkFontFaceParity(input.cssContent, meta, issues);
274
+ checkPreviewSwatches(meta, issues);
275
+ checkCommercialDenylist(input.cssContent, meta, issues);
276
+ }
277
+ checkOflPresence(input.fontFiles, issues);
278
+ checkPayloadBudget(input.totalPayloadBytes, issues);
279
+ const valid = !issues.some((i) => i.severity === "error");
280
+ return { valid, issues, ...meta ? { meta } : {} };
281
+ }
282
+ export {
283
+ validateThemePack
284
+ };
@@ -13,10 +13,8 @@ export declare function readColorSchemeFromDom(defaultMode: ColorSchemeMode): Co
13
13
  * `color-scheme-changed` window event.
14
14
  *
15
15
  * Tweak-state reconciliation is intentionally NOT done here (#2037). The zdtp
16
- * panel owns its own storage lifecycle: it persists the unified tweak envelope
17
- * under `zudo-doc-tweak-state-v4` (auto-migrating the legacy
18
- * `zudo-doc-tweak-state-v3` / `-v2` / `zudo-doc-tweak-state` (v1) keys into
19
- * it), and its own `color-scheme-changed` listener clears applied inline
16
+ * panel owns its own storage lifecycle and current persisted-state contract;
17
+ * its own `color-scheme-changed` listener clears applied inline
20
18
  * styles and re-seeds the color slice from the newly active scheme. An
21
19
  * earlier version of this function deleted `zudo-doc-tweak-state` + `-v2` on
22
20
  * every toggle, which (a) targeted stale keys after zdtp moved to v3 — so it