@refrakt-md/runes 0.33.0 → 0.34.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 (289) hide show
  1. package/dist/aggregate-resolve.d.ts.map +1 -1
  2. package/dist/aggregate-resolve.js +18 -4
  3. package/dist/aggregate-resolve.js.map +1 -1
  4. package/dist/attributes.d.ts +15 -0
  5. package/dist/attributes.d.ts.map +1 -1
  6. package/dist/attributes.js +22 -7
  7. package/dist/attributes.js.map +1 -1
  8. package/dist/collection-helpers.d.ts.map +1 -1
  9. package/dist/collection-helpers.js +1 -1
  10. package/dist/collection-helpers.js.map +1 -1
  11. package/dist/collection-resolve.d.ts.map +1 -1
  12. package/dist/collection-resolve.js +31 -8
  13. package/dist/collection-resolve.js.map +1 -1
  14. package/dist/config.d.ts.map +1 -1
  15. package/dist/config.js +195 -74
  16. package/dist/config.js.map +1 -1
  17. package/dist/data-adapters.d.ts.map +1 -1
  18. package/dist/data-adapters.js +28 -11
  19. package/dist/data-adapters.js.map +1 -1
  20. package/dist/data-emit.d.ts.map +1 -1
  21. package/dist/data-emit.js.map +1 -1
  22. package/dist/data-pipeline.d.ts.map +1 -1
  23. package/dist/data-pipeline.js +45 -12
  24. package/dist/data-pipeline.js.map +1 -1
  25. package/dist/data-projection.d.ts.map +1 -1
  26. package/dist/data-projection.js +4 -3
  27. package/dist/data-projection.js.map +1 -1
  28. package/dist/data-resolve.d.ts.map +1 -1
  29. package/dist/data-resolve.js +5 -2
  30. package/dist/data-resolve.js.map +1 -1
  31. package/dist/documents/page.d.ts.map +1 -1
  32. package/dist/documents/page.js.map +1 -1
  33. package/dist/drawer-pipeline.d.ts.map +1 -1
  34. package/dist/drawer-pipeline.js +3 -2
  35. package/dist/drawer-pipeline.js.map +1 -1
  36. package/dist/expand-pipeline.d.ts.map +1 -1
  37. package/dist/expand-pipeline.js +3 -3
  38. package/dist/expand-pipeline.js.map +1 -1
  39. package/dist/fence-escape.d.ts.map +1 -1
  40. package/dist/fence-escape.js +1 -3
  41. package/dist/fence-escape.js.map +1 -1
  42. package/dist/field-match.d.ts.map +1 -1
  43. package/dist/field-match.js.map +1 -1
  44. package/dist/file-ref-resolve.js +6 -4
  45. package/dist/file-ref-resolve.js.map +1 -1
  46. package/dist/fixtures.js +2 -2
  47. package/dist/fixtures.js.map +1 -1
  48. package/dist/functions.d.ts.map +1 -1
  49. package/dist/functions.js +16 -3
  50. package/dist/functions.js.map +1 -1
  51. package/dist/include-pipeline.d.ts.map +1 -1
  52. package/dist/include-pipeline.js +3 -1
  53. package/dist/include-pipeline.js.map +1 -1
  54. package/dist/index.d.ts +92 -37
  55. package/dist/index.d.ts.map +1 -1
  56. package/dist/index.js +281 -60
  57. package/dist/index.js.map +1 -1
  58. package/dist/interfaces.d.ts.map +1 -1
  59. package/dist/interfaces.js.map +1 -1
  60. package/dist/layouts/grid.d.ts +1 -1
  61. package/dist/layouts/grid.d.ts.map +1 -1
  62. package/dist/layouts/grid.js +4 -6
  63. package/dist/layouts/grid.js.map +1 -1
  64. package/dist/lib/component.d.ts.map +1 -1
  65. package/dist/lib/component.js +7 -7
  66. package/dist/lib/component.js.map +1 -1
  67. package/dist/lib/icon-resolve.d.ts.map +1 -1
  68. package/dist/lib/icon-resolve.js.map +1 -1
  69. package/dist/lib/image-schemes.js +2 -2
  70. package/dist/lib/image-schemes.js.map +1 -1
  71. package/dist/lib/index.d.ts +1 -1
  72. package/dist/lib/index.d.ts.map +1 -1
  73. package/dist/lib/index.js +251 -50
  74. package/dist/lib/index.js.map +1 -1
  75. package/dist/lib/node.d.ts.map +1 -1
  76. package/dist/lib/node.js +3 -2
  77. package/dist/lib/node.js.map +1 -1
  78. package/dist/lib/placeholder.d.ts.map +1 -1
  79. package/dist/lib/placeholder.js +6 -9
  80. package/dist/lib/placeholder.js.map +1 -1
  81. package/dist/lib/read-file.d.ts.map +1 -1
  82. package/dist/lib/read-file.js.map +1 -1
  83. package/dist/lib/renderable.d.ts.map +1 -1
  84. package/dist/lib/renderable.js +5 -5
  85. package/dist/lib/renderable.js.map +1 -1
  86. package/dist/lib/resolver.d.ts.map +1 -1
  87. package/dist/lib/resolver.js +26 -35
  88. package/dist/lib/resolver.js.map +1 -1
  89. package/dist/lib/svg.d.ts.map +1 -1
  90. package/dist/lib/svg.js.map +1 -1
  91. package/dist/nodes.d.ts.map +1 -1
  92. package/dist/nodes.js +9 -11
  93. package/dist/nodes.js.map +1 -1
  94. package/dist/outline-scope.js +1 -3
  95. package/dist/outline-scope.js.map +1 -1
  96. package/dist/plugins.d.ts.map +1 -1
  97. package/dist/plugins.js +13 -10
  98. package/dist/plugins.js.map +1 -1
  99. package/dist/reference.d.ts.map +1 -1
  100. package/dist/reference.js +28 -22
  101. package/dist/reference.js.map +1 -1
  102. package/dist/relationships-resolve.d.ts.map +1 -1
  103. package/dist/relationships-resolve.js +31 -7
  104. package/dist/relationships-resolve.js.map +1 -1
  105. package/dist/rune.d.ts.map +1 -1
  106. package/dist/rune.js.map +1 -1
  107. package/dist/sandbox-sources.js +6 -6
  108. package/dist/sandbox-sources.js.map +1 -1
  109. package/dist/seo.d.ts.map +1 -1
  110. package/dist/seo.js +4 -4
  111. package/dist/seo.js.map +1 -1
  112. package/dist/snippet-pipeline.d.ts.map +1 -1
  113. package/dist/snippet-pipeline.js +1 -1
  114. package/dist/snippet-pipeline.js.map +1 -1
  115. package/dist/tags/accordion.d.ts.map +1 -1
  116. package/dist/tags/accordion.js +23 -9
  117. package/dist/tags/accordion.js.map +1 -1
  118. package/dist/tags/aggregate.d.ts.map +1 -1
  119. package/dist/tags/aggregate.js +65 -10
  120. package/dist/tags/aggregate.js.map +1 -1
  121. package/dist/tags/annotate.d.ts.map +1 -1
  122. package/dist/tags/annotate.js +12 -9
  123. package/dist/tags/annotate.js.map +1 -1
  124. package/dist/tags/badge.d.ts.map +1 -1
  125. package/dist/tags/badge.js.map +1 -1
  126. package/dist/tags/bar.d.ts.map +1 -1
  127. package/dist/tags/bar.js +3 -7
  128. package/dist/tags/bar.js.map +1 -1
  129. package/dist/tags/bg.d.ts.map +1 -1
  130. package/dist/tags/bg.js +60 -12
  131. package/dist/tags/bg.js.map +1 -1
  132. package/dist/tags/blog.d.ts.map +1 -1
  133. package/dist/tags/blog.js +35 -10
  134. package/dist/tags/blog.js.map +1 -1
  135. package/dist/tags/breadcrumb.d.ts.map +1 -1
  136. package/dist/tags/breadcrumb.js +33 -11
  137. package/dist/tags/breadcrumb.js.map +1 -1
  138. package/dist/tags/budget.d.ts.map +1 -1
  139. package/dist/tags/budget.js +54 -16
  140. package/dist/tags/budget.js.map +1 -1
  141. package/dist/tags/card.d.ts.map +1 -1
  142. package/dist/tags/card.js +24 -6
  143. package/dist/tags/card.js.map +1 -1
  144. package/dist/tags/chart.d.ts.map +1 -1
  145. package/dist/tags/chart.js +33 -11
  146. package/dist/tags/chart.js.map +1 -1
  147. package/dist/tags/codegroup.d.ts.map +1 -1
  148. package/dist/tags/codegroup.js +39 -21
  149. package/dist/tags/codegroup.js.map +1 -1
  150. package/dist/tags/collection.d.ts.map +1 -1
  151. package/dist/tags/collection.js +55 -9
  152. package/dist/tags/collection.js.map +1 -1
  153. package/dist/tags/common.d.ts.map +1 -1
  154. package/dist/tags/common.js +34 -9
  155. package/dist/tags/common.js.map +1 -1
  156. package/dist/tags/compare.d.ts.map +1 -1
  157. package/dist/tags/compare.js +26 -14
  158. package/dist/tags/compare.js.map +1 -1
  159. package/dist/tags/conversation.d.ts.map +1 -1
  160. package/dist/tags/conversation.js +19 -17
  161. package/dist/tags/conversation.js.map +1 -1
  162. package/dist/tags/data.d.ts.map +1 -1
  163. package/dist/tags/data.js +67 -13
  164. package/dist/tags/data.js.map +1 -1
  165. package/dist/tags/datatable.d.ts.map +1 -1
  166. package/dist/tags/datatable.js +22 -8
  167. package/dist/tags/datatable.js.map +1 -1
  168. package/dist/tags/deflist.d.ts.map +1 -1
  169. package/dist/tags/deflist.js +5 -11
  170. package/dist/tags/deflist.js.map +1 -1
  171. package/dist/tags/details.d.ts.map +1 -1
  172. package/dist/tags/details.js +8 -5
  173. package/dist/tags/details.js.map +1 -1
  174. package/dist/tags/diagram.d.ts.map +1 -1
  175. package/dist/tags/diagram.js +9 -5
  176. package/dist/tags/diagram.js.map +1 -1
  177. package/dist/tags/diff.d.ts.map +1 -1
  178. package/dist/tags/diff.js +43 -24
  179. package/dist/tags/diff.js.map +1 -1
  180. package/dist/tags/drawer.d.ts.map +1 -1
  181. package/dist/tags/drawer.js +4 -6
  182. package/dist/tags/drawer.js.map +1 -1
  183. package/dist/tags/embed.d.ts.map +1 -1
  184. package/dist/tags/embed.js +10 -5
  185. package/dist/tags/embed.js.map +1 -1
  186. package/dist/tags/expand.d.ts.map +1 -1
  187. package/dist/tags/expand.js.map +1 -1
  188. package/dist/tags/figure.d.ts.map +1 -1
  189. package/dist/tags/figure.js +29 -9
  190. package/dist/tags/figure.js.map +1 -1
  191. package/dist/tags/file-ref.d.ts.map +1 -1
  192. package/dist/tags/file-ref.js.map +1 -1
  193. package/dist/tags/form.d.ts.map +1 -1
  194. package/dist/tags/form.js +52 -25
  195. package/dist/tags/form.js.map +1 -1
  196. package/dist/tags/gallery.d.ts.map +1 -1
  197. package/dist/tags/gallery.js +26 -12
  198. package/dist/tags/gallery.js.map +1 -1
  199. package/dist/tags/grid.d.ts.map +1 -1
  200. package/dist/tags/grid.js +57 -14
  201. package/dist/tags/grid.js.map +1 -1
  202. package/dist/tags/hint.d.ts.map +1 -1
  203. package/dist/tags/hint.js +9 -5
  204. package/dist/tags/hint.js.map +1 -1
  205. package/dist/tags/icon.d.ts.map +1 -1
  206. package/dist/tags/icon.js +5 -1
  207. package/dist/tags/icon.js.map +1 -1
  208. package/dist/tags/include.d.ts.map +1 -1
  209. package/dist/tags/include.js +1 -1
  210. package/dist/tags/include.js.map +1 -1
  211. package/dist/tags/juxtapose.d.ts.map +1 -1
  212. package/dist/tags/juxtapose.js +32 -14
  213. package/dist/tags/juxtapose.js.map +1 -1
  214. package/dist/tags/layout.d.ts.map +1 -1
  215. package/dist/tags/layout.js +7 -4
  216. package/dist/tags/layout.js.map +1 -1
  217. package/dist/tags/mediatext.d.ts.map +1 -1
  218. package/dist/tags/mediatext.js +19 -8
  219. package/dist/tags/mediatext.js.map +1 -1
  220. package/dist/tags/nav.d.ts.map +1 -1
  221. package/dist/tags/nav.js +43 -23
  222. package/dist/tags/nav.js.map +1 -1
  223. package/dist/tags/pagination.d.ts.map +1 -1
  224. package/dist/tags/pagination.js +27 -5
  225. package/dist/tags/pagination.js.map +1 -1
  226. package/dist/tags/progress.d.ts.map +1 -1
  227. package/dist/tags/progress.js +25 -5
  228. package/dist/tags/progress.js.map +1 -1
  229. package/dist/tags/pullquote.d.ts.map +1 -1
  230. package/dist/tags/pullquote.js +16 -9
  231. package/dist/tags/pullquote.js.map +1 -1
  232. package/dist/tags/region.d.ts.map +1 -1
  233. package/dist/tags/region.js +9 -4
  234. package/dist/tags/region.js.map +1 -1
  235. package/dist/tags/relationships.d.ts.map +1 -1
  236. package/dist/tags/relationships.js +55 -9
  237. package/dist/tags/relationships.js.map +1 -1
  238. package/dist/tags/reveal.d.ts.map +1 -1
  239. package/dist/tags/reveal.js +16 -7
  240. package/dist/tags/reveal.js.map +1 -1
  241. package/dist/tags/sandbox.d.ts.map +1 -1
  242. package/dist/tags/sandbox.js +104 -44
  243. package/dist/tags/sandbox.js.map +1 -1
  244. package/dist/tags/section.d.ts.map +1 -1
  245. package/dist/tags/section.js +13 -3
  246. package/dist/tags/section.js.map +1 -1
  247. package/dist/tags/showcase.d.ts.map +1 -1
  248. package/dist/tags/showcase.js +33 -11
  249. package/dist/tags/showcase.js.map +1 -1
  250. package/dist/tags/sidenote.d.ts.map +1 -1
  251. package/dist/tags/sidenote.js +9 -5
  252. package/dist/tags/sidenote.js.map +1 -1
  253. package/dist/tags/snippet.d.ts.map +1 -1
  254. package/dist/tags/snippet.js.map +1 -1
  255. package/dist/tags/tabs.d.ts.map +1 -1
  256. package/dist/tags/tabs.js +16 -9
  257. package/dist/tags/tabs.js.map +1 -1
  258. package/dist/tags/textblock.d.ts.map +1 -1
  259. package/dist/tags/textblock.js +9 -5
  260. package/dist/tags/textblock.js.map +1 -1
  261. package/dist/tags/tint.d.ts +1 -1
  262. package/dist/tags/tint.d.ts.map +1 -1
  263. package/dist/tags/tint.js +14 -2
  264. package/dist/tags/tint.js.map +1 -1
  265. package/dist/tags/toc.d.ts.map +1 -1
  266. package/dist/tags/toc.js +16 -7
  267. package/dist/tags/toc.js.map +1 -1
  268. package/dist/tags/xref.d.ts.map +1 -1
  269. package/dist/tags/xref.js.map +1 -1
  270. package/dist/universal-attributes.d.ts.map +1 -1
  271. package/dist/universal-attributes.js +28 -5
  272. package/dist/universal-attributes.js.map +1 -1
  273. package/dist/util.d.ts.map +1 -1
  274. package/dist/util.js +4 -4
  275. package/dist/util.js.map +1 -1
  276. package/dist/xref-patterns.js +1 -1
  277. package/dist/xref-patterns.js.map +1 -1
  278. package/dist/xref-preview-resolve.js +3 -4
  279. package/dist/xref-preview-resolve.js.map +1 -1
  280. package/dist/xref-resolve.d.ts.map +1 -1
  281. package/dist/xref-resolve.js +4 -4
  282. package/dist/xref-resolve.js.map +1 -1
  283. package/i18n/de.json +67 -67
  284. package/i18n/en.json +67 -67
  285. package/package.json +3 -3
  286. package/dist/tags/error.d.ts +0 -3
  287. package/dist/tags/error.d.ts.map +0 -1
  288. package/dist/tags/error.js +0 -34
  289. package/dist/tags/error.js.map +0 -1
package/dist/index.js CHANGED
@@ -1,7 +1,6 @@
1
- import { heading, paragraph, fence, list, item, em, strong, text, link, hardbreak, image, table, td } from './nodes.js';
1
+ import { heading, paragraph, fence, list, item, em, strong, text, link, hardbreak, image, table, td, } from './nodes.js';
2
2
  export { Page } from './documents/page.js';
3
3
  import { DocPage } from './documents/doc.js';
4
- import { error } from './tags/error.js';
5
4
  import { grid } from './tags/grid.js';
6
5
  import { codegroup } from './tags/codegroup.js';
7
6
  import { snippet } from './tags/snippet.js';
@@ -63,18 +62,24 @@ import Markdoc from '@markdoc/markdoc';
63
62
  import { defineRune, runeTagMap } from './rune.js';
64
63
  export * from './interfaces.js';
65
64
  export { Rune, defineRune, runeTagMap } from './rune.js';
65
+ /** Custom Markdoc attribute types. Exported since SPEC-132, which is the first
66
+ * release in which their `validate()` runs in a build at all — `transform()`
67
+ * never invoked it, only `Markdoc.validate()` does. `plugins/media` carries its
68
+ * own copies of these classes, which is what an unexported utility tends to
69
+ * produce. */
70
+ export { SeparatedString, CommaSeparatedList, SpaceSeparatedList, SpaceSeparatedNumberList, } from './attributes.js';
66
71
  export { RenderableNodeCursor } from './lib/renderable.js';
67
- export { createContentModelSchema, createComponentRenderable, asNodes, schemaContentModels, schemaRuneStructures, declareUniversalPosture, sanitizeSandboxContent } from './lib/index.js';
72
+ export { createContentModelSchema, createComponentRenderable, asNodes, schemaContentModels, schemaRuneStructures, declareUniversalPosture, sanitizeSandboxContent, } from './lib/index.js';
68
73
  // SPEC-125 Phase 3 — the declared rule for universal-attribute availability
69
- export { resolveUniversalAttributes, AXIS_ATTRIBUTES, POSTURE_REASONS } from './universal-attributes.js';
74
+ export { resolveUniversalAttributes, AXIS_ATTRIBUTES, POSTURE_REASONS, } from './universal-attributes.js';
70
75
  export { describeSchemaUniversals, UNRECORDED_REASON } from './schema-universals.js';
71
- export { resolve, resolveSequence, resolveDelimited, resolveContentModel, resolveListItems, evaluateCondition, matchesType } from './lib/resolver.js';
76
+ export { resolve, resolveSequence, resolveDelimited, resolveContentModel, resolveListItems, evaluateCondition, matchesType, } from './lib/resolver.js';
72
77
  export { registerImageScheme, resolveImageScheme, hasImageScheme } from './lib/image-schemes.js';
73
78
  export { resolveIcon, splitIconName } from './lib/icon-resolve.js';
74
- export { placeholderSvg, PLACEHOLDER_SHAPES, DEFAULT_PLACEHOLDER_SHAPE } from './lib/placeholder.js';
79
+ export { placeholderSvg, PLACEHOLDER_SHAPES, DEFAULT_PLACEHOLDER_SHAPE, } from './lib/placeholder.js';
75
80
  export { FIXTURE_ROLES, splitFixture, parseFixtureFilename, validateFixtureFrontmatter, parseFixture, } from './fixtures.js';
76
- export { parseFieldMatch, matchesFieldMatch, matchesFilterExpr, resolveEntityField } from './field-match.js';
77
- export { DEFERRED_BODY_ATTR, captureDeferredBodies, readDeferredBody, transformDeferredTemplate } from './deferred-body.js';
81
+ export { parseFieldMatch, matchesFieldMatch, matchesFilterExpr, resolveEntityField, } from './field-match.js';
82
+ export { DEFERRED_BODY_ATTR, captureDeferredBodies, readDeferredBody, transformDeferredTemplate, } from './deferred-body.js';
78
83
  export { resolveCollections } from './collection-resolve.js';
79
84
  export { resolveRelationships } from './relationships-resolve.js';
80
85
  export { resolveAggregates } from './aggregate-resolve.js';
@@ -88,8 +93,8 @@ export { hoistPreviewDrawers, registerHoistBuilder, getHoistBuilder, pathToSlug,
88
93
  export { Ordering, buildOrdering, sortEntities, groupEntities, groupBy, entityUrl, entityTitle, fieldValue, titleLink, projectItem, renderItemTemplate, } from './collection-helpers.js';
89
94
  export { COLLECTION_SENTINEL } from './tags/collection.js';
90
95
  export { functions, currency, date, number, join, concat, humanize } from './functions.js';
91
- export { linkItem, pageSectionProperties, buildLayoutMetas, splitMediaBodyFooter, extractMediaImage, unwrapParagraphImages, isMediaNode, isSchemeMediaNode, name as nameHelper, description as descriptionHelper, SplitablePageSectionModel, SplitLayoutModel, splitLayoutAttributes } from './tags/common.js';
92
- export { extractHeadings, firstH1, headingsToList, headingSlug, headingText, renderableText } from './util.js';
96
+ export { linkItem, pageSectionProperties, buildLayoutMetas, splitMediaBodyFooter, extractMediaImage, unwrapParagraphImages, isMediaNode, isSchemeMediaNode, name as nameHelper, description as descriptionHelper, SplitablePageSectionModel, SplitLayoutModel, splitLayoutAttributes, } from './tags/common.js';
97
+ export { extractHeadings, firstH1, headingsToList, headingSlug, headingText, renderableText, } from './util.js';
93
98
  export { LANG_MAP, FALLBACK_LANG, inferLanguage } from './lang-map.js';
94
99
  export { extractSeo, collectJsonLd, textContent } from './seo.js';
95
100
  export { serialize, serializeTree } from './serialize.js';
@@ -97,9 +102,9 @@ export { RUNE_EXAMPLES, RUNE_FIXTURE_META } from './examples.js';
97
102
  export { describeRune, renderContentModel, serializeContentModel, stripContentModel, hydrateRuneInfo, hydrateAllRuneInfos, hydrateRuneByName, serializeRune, groupReferenceInfos, renderReferenceMarkdown, EXCLUDED_RUNES, HIDDEN_ATTRIBUTES, } from './reference.js';
98
103
  export { registerAttributePreset, lookupAttributePreset, schemaBasePresets, UNIVERSAL_ATTRIBUTE_NAMES, } from './attribute-presets.js';
99
104
  export { LAYOUT, CANONICAL_LAYOUTS, layoutMatches } from './layout-vocabulary.js';
100
- export { READING_REGISTERS, DEFAULT_READING, READING_CAPABILITIES, resolveReading, coerceRegister } from '@refrakt-md/transform';
101
- export { loadPlugin, mergePlugins, applyAliases, loadLocalRunes, discoverPluginFixtures, discoverPluginFixtureManifest, assertFileRootNamespaceAllowed } from './plugins.js';
102
- export { coreConfig, baseConfig, corePipelineHooks, createCorePipelineHooks, resolveCoreSentinels } from './config.js';
105
+ export { READING_REGISTERS, DEFAULT_READING, READING_CAPABILITIES, resolveReading, coerceRegister, } from '@refrakt-md/transform';
106
+ export { loadPlugin, mergePlugins, applyAliases, loadLocalRunes, discoverPluginFixtures, discoverPluginFixtureManifest, assertFileRootNamespaceAllowed, } from './plugins.js';
107
+ export { coreConfig, baseConfig, corePipelineHooks, createCorePipelineHooks, resolveCoreSentinels, } from './config.js';
103
108
  // SPEC-035 — first-party core translation bundles (generated from i18n/*.json).
104
109
  export { coreTranslations } from './translations.generated.js';
105
110
  export { BREADCRUMB_AUTO_SENTINEL } from './tags/breadcrumb.js';
@@ -120,7 +125,14 @@ export const runes = {
120
125
  description: 'Navigation structure with page slug references and optional grouping',
121
126
  typeName: 'Nav',
122
127
  category: 'Site',
123
- snippet: ['{% nav %}', '## ${1:Section}', '', '- ${2:page-slug}', '- ${3:another-page}', '{% /nav %}'],
128
+ snippet: [
129
+ '{% nav %}',
130
+ '## ${1:Section}',
131
+ '',
132
+ '- ${2:page-slug}',
133
+ '- ${3:another-page}',
134
+ '{% /nav %}',
135
+ ],
124
136
  }),
125
137
  region: defineRune({
126
138
  name: 'region',
@@ -133,7 +145,13 @@ export const runes = {
133
145
  schema: layout,
134
146
  description: 'Layout definition containing named regions',
135
147
  category: 'Site',
136
- snippet: ['{% layout %}', '{% region name="${1:header}" %}', '$0', '{% /region %}', '{% /layout %}'],
148
+ snippet: [
149
+ '{% layout %}',
150
+ '{% region name="${1:header}" %}',
151
+ '$0',
152
+ '{% /region %}',
153
+ '{% /layout %}',
154
+ ],
137
155
  }),
138
156
  codegroup: defineRune({
139
157
  name: 'codegroup',
@@ -141,14 +159,17 @@ export const runes = {
141
159
  description: 'Tabbed code block with language tabs',
142
160
  typeName: 'CodeGroup',
143
161
  category: 'Code & Data',
144
- snippet: ['{% codegroup %}', '```${1:js}', '$0', '```', '', '```${2:ts}', '', '```', '{% /codegroup %}'],
145
- }),
146
- error: defineRune({
147
- name: 'error',
148
- schema: error,
149
- description: 'Error reporting table',
150
- typeName: 'Error',
151
- category: 'Semantic',
162
+ snippet: [
163
+ '{% codegroup %}',
164
+ '```${1:js}',
165
+ '$0',
166
+ '```',
167
+ '',
168
+ '```${2:ts}',
169
+ '',
170
+ '```',
171
+ '{% /codegroup %}',
172
+ ],
152
173
  }),
153
174
  grid: defineRune({
154
175
  name: 'grid',
@@ -157,7 +178,15 @@ export const runes = {
157
178
  description: 'Grid layout container with configurable columns and rows',
158
179
  typeName: 'Grid',
159
180
  category: 'Layout',
160
- snippet: ['{% grid columns=${1:2} %}', '${2:First column content}', '', '---', '', '${3:Second column content}', '{% /grid %}'],
181
+ snippet: [
182
+ '{% grid columns=${1:2} %}',
183
+ '${2:First column content}',
184
+ '',
185
+ '---',
186
+ '',
187
+ '${3:Second column content}',
188
+ '{% /grid %}',
189
+ ],
161
190
  }),
162
191
  hint: defineRune({
163
192
  name: 'hint',
@@ -180,7 +209,17 @@ export const runes = {
180
209
  description: 'Tabbed interface with tab panels',
181
210
  typeName: 'TabGroup',
182
211
  category: 'Layout',
183
- snippet: ['{% tabs %}', '## ${1:Tab One}', '', '${2:Content for tab one.}', '', '## ${3:Tab Two}', '', '${4:Content for tab two.}', '{% /tabs %}'],
212
+ snippet: [
213
+ '{% tabs %}',
214
+ '## ${1:Tab One}',
215
+ '',
216
+ '${2:Content for tab one.}',
217
+ '',
218
+ '## ${3:Tab Two}',
219
+ '',
220
+ '${4:Content for tab two.}',
221
+ '{% /tabs %}',
222
+ ],
184
223
  }),
185
224
  details: defineRune({
186
225
  name: 'details',
@@ -196,25 +235,43 @@ export const runes = {
196
235
  description: 'Modal side panel addressed by id. Triggered by xrefs anywhere on the page; falls back to in-flow rendering without JS.',
197
236
  typeName: 'Drawer',
198
237
  category: 'Layout',
199
- snippet: ['{% drawer id="${1:auth-explainer}" title="${2:Auth system}" %}', '$0', '{% /drawer %}'],
238
+ snippet: [
239
+ '{% drawer id="${1:auth-explainer}" title="${2:Auth system}" %}',
240
+ '$0',
241
+ '{% /drawer %}',
242
+ ],
200
243
  }),
201
244
  figure: defineRune({
202
245
  name: 'figure',
203
246
  schema: figure,
204
247
  description: 'Enhanced image with caption, attribution, and sizing',
205
248
  seoType: 'ImageObject',
206
- typeName: 'Figure', schemaOrgType: 'ImageObject',
249
+ typeName: 'Figure',
250
+ schemaOrgType: 'ImageObject',
207
251
  category: 'Content',
208
- snippet: ['{% figure size="${1|medium,small,large,full|}" %}', '![${2:Alt text}](${3:/path/to/image.png})', '', '${4:Caption text}', '{% /figure %}'],
252
+ snippet: [
253
+ '{% figure size="${1|medium,small,large,full|}" %}',
254
+ '![${2:Alt text}](${3:/path/to/image.png})',
255
+ '',
256
+ '${4:Caption text}',
257
+ '{% /figure %}',
258
+ ],
209
259
  }),
210
260
  gallery: defineRune({
211
261
  name: 'gallery',
212
262
  schema: gallery,
213
263
  description: 'Multi-image container with grid, carousel, or masonry layout and optional lightbox',
214
264
  seoType: 'ImageGallery',
215
- typeName: 'Gallery', schemaOrgType: 'ImageGallery',
265
+ typeName: 'Gallery',
266
+ schemaOrgType: 'ImageGallery',
216
267
  category: 'Content',
217
- snippet: ['{% gallery layout="${1|grid,carousel,masonry|}" %}', '![${2:Alt text}](${3:/path/to/image1.png})', '', '![${4:Alt text}](${5:/path/to/image2.png})', '{% /gallery %}'],
268
+ snippet: [
269
+ '{% gallery layout="${1|grid,carousel,masonry|}" %}',
270
+ '![${2:Alt text}](${3:/path/to/image1.png})',
271
+ '',
272
+ '![${4:Alt text}](${5:/path/to/image2.png})',
273
+ '{% /gallery %}',
274
+ ],
218
275
  }),
219
276
  accordion: defineRune({
220
277
  name: 'accordion',
@@ -222,15 +279,27 @@ export const runes = {
222
279
  schema: accordion,
223
280
  description: 'Collapsible accordion sections where headings become toggleable headers',
224
281
  seoType: 'FAQPage',
225
- typeName: 'Accordion', schemaOrgType: 'FAQPage',
282
+ typeName: 'Accordion',
283
+ schemaOrgType: 'FAQPage',
226
284
  category: 'Layout',
227
- snippet: ['{% accordion %}', '## ${1:First Question}', '', '${2:Answer to the first question.}', '', '## ${3:Second Question}', '', '${4:Answer to the second question.}', '{% /accordion %}'],
285
+ snippet: [
286
+ '{% accordion %}',
287
+ '## ${1:First Question}',
288
+ '',
289
+ '${2:Answer to the first question.}',
290
+ '',
291
+ '## ${3:Second Question}',
292
+ '',
293
+ '${4:Answer to the second question.}',
294
+ '{% /accordion %}',
295
+ ],
228
296
  }),
229
297
  'accordion-item': defineRune({
230
298
  name: 'accordion-item',
231
299
  schema: accordionItem,
232
300
  description: 'Individual accordion section',
233
- typeName: 'AccordionItem', schemaOrgType: 'Question',
301
+ typeName: 'AccordionItem',
302
+ schemaOrgType: 'Question',
234
303
  }),
235
304
  toc: defineRune({
236
305
  name: 'toc',
@@ -246,7 +315,8 @@ export const runes = {
246
315
  schema: embed,
247
316
  description: 'Embedded content from external services (YouTube, Twitter, CodePen, Spotify)',
248
317
  seoType: 'VideoObject',
249
- typeName: 'Embed', schemaOrgType: 'VideoObject',
318
+ typeName: 'Embed',
319
+ schemaOrgType: 'VideoObject',
250
320
  category: 'Content',
251
321
  snippet: ['{% embed url="${1:https://}" /%}'],
252
322
  }),
@@ -255,7 +325,8 @@ export const runes = {
255
325
  schema: breadcrumb,
256
326
  description: 'Navigation breadcrumb trail showing page hierarchy',
257
327
  seoType: 'BreadcrumbList',
258
- typeName: 'Breadcrumb', schemaOrgType: 'BreadcrumbList',
328
+ typeName: 'Breadcrumb',
329
+ schemaOrgType: 'BreadcrumbList',
259
330
  category: 'Site',
260
331
  snippet: ['{% breadcrumb /%}'],
261
332
  }),
@@ -272,9 +343,17 @@ export const runes = {
272
343
  schema: budget,
273
344
  description: 'Structured cost breakdown with categories, line items, and auto-calculated totals',
274
345
  seoType: 'ItemList',
275
- typeName: 'Budget', schemaOrgType: 'ItemList',
346
+ typeName: 'Budget',
347
+ schemaOrgType: 'ItemList',
276
348
  category: 'Semantic',
277
- snippet: ['{% budget %}', '## ${1:Category}', '', '- ${2:Item description}: \\$${3:100}', '- ${4:Another item}: \\$${5:200}', '{% /budget %}'],
349
+ snippet: [
350
+ '{% budget %}',
351
+ '## ${1:Category}',
352
+ '',
353
+ '- ${2:Item description}: \\$${3:100}',
354
+ '- ${4:Another item}: \\$${5:200}',
355
+ '{% /budget %}',
356
+ ],
278
357
  }),
279
358
  'budget-category': defineRune({
280
359
  name: 'budget-category',
@@ -294,7 +373,17 @@ export const runes = {
294
373
  description: 'Side-by-side code comparison with labeled panels',
295
374
  typeName: 'Compare',
296
375
  category: 'Code & Data',
297
- snippet: ['{% compare %}', '```${1:js}', '${2:// Before}', '```', '', '```${3:js}', '${4:// After}', '```', '{% /compare %}'],
376
+ snippet: [
377
+ '{% compare %}',
378
+ '```${1:js}',
379
+ '${2:// Before}',
380
+ '```',
381
+ '',
382
+ '```${3:js}',
383
+ '${4:// After}',
384
+ '```',
385
+ '{% /compare %}',
386
+ ],
298
387
  }),
299
388
  datatable: defineRune({
300
389
  name: 'datatable',
@@ -302,9 +391,16 @@ export const runes = {
302
391
  schema: datatable,
303
392
  description: 'Interactive data table with sorting, filtering, and pagination from a Markdown table',
304
393
  seoType: 'Dataset',
305
- typeName: 'DataTable', schemaOrgType: 'Dataset',
394
+ typeName: 'DataTable',
395
+ schemaOrgType: 'Dataset',
306
396
  category: 'Code & Data',
307
- snippet: ['{% datatable %}', '| ${1:Column A} | ${2:Column B} | ${3:Column C} |', '|---|---|---|', '| ${4:Data} | ${5:Data} | ${6:Data} |', '{% /datatable %}'],
397
+ snippet: [
398
+ '{% datatable %}',
399
+ '| ${1:Column A} | ${2:Column B} | ${3:Column C} |',
400
+ '|---|---|---|',
401
+ '| ${4:Data} | ${5:Data} | ${6:Data} |',
402
+ '{% /datatable %}',
403
+ ],
308
404
  }),
309
405
  diff: defineRune({
310
406
  name: 'diff',
@@ -312,7 +408,17 @@ export const runes = {
312
408
  description: 'Side-by-side or unified diff view between two code blocks',
313
409
  typeName: 'Diff',
314
410
  category: 'Code & Data',
315
- snippet: ['{% diff %}', '```${1:js}', '${2:// Before}', '```', '', '```${3:js}', '${4:// After}', '```', '{% /diff %}'],
411
+ snippet: [
412
+ '{% diff %}',
413
+ '```${1:js}',
414
+ '${2:// Before}',
415
+ '```',
416
+ '',
417
+ '```${3:js}',
418
+ '${4:// After}',
419
+ '```',
420
+ '{% /diff %}',
421
+ ],
316
422
  }),
317
423
  snippet: defineRune({
318
424
  name: 'snippet',
@@ -341,7 +447,7 @@ export const runes = {
341
447
  include: defineRune({
342
448
  name: 'include',
343
449
  schema: include,
344
- description: 'Paste a partial\'s AST into the page before the preprocess phase, so `data` and `snippet` inside it resolve — the case `{% partial %}` cannot serve. Reads the same `_partials/` and file roots (SPEC-129).',
450
+ description: "Paste a partial's AST into the page before the preprocess phase, so `data` and `snippet` inside it resolve — the case `{% partial %}` cannot serve. Reads the same `_partials/` and file roots (SPEC-129).",
345
451
  typeName: 'Include',
346
452
  category: 'Code & Data',
347
453
  snippet: ['{% include file="${1:shared-block.md}" /%}'],
@@ -352,7 +458,14 @@ export const runes = {
352
458
  description: 'Chart visualization from a Markdown table. First column becomes axis labels, header row becomes series names.',
353
459
  typeName: 'Chart',
354
460
  category: 'Code & Data',
355
- snippet: ['{% chart type="${1|bar,line,pie,area|}" %}', '| ${2:Label} | ${3:Series A} | ${4:Series B} |', '|---|---|---|', '| ${5:Item 1} | ${6:10} | ${7:20} |', '| ${8:Item 2} | ${9:30} | ${10:15} |', '{% /chart %}'],
461
+ snippet: [
462
+ '{% chart type="${1|bar,line,pie,area|}" %}',
463
+ '| ${2:Label} | ${3:Series A} | ${4:Series B} |',
464
+ '|---|---|---|',
465
+ '| ${5:Item 1} | ${6:10} | ${7:20} |',
466
+ '| ${8:Item 2} | ${9:30} | ${10:15} |',
467
+ '{% /chart %}',
468
+ ],
356
469
  }),
357
470
  diagram: defineRune({
358
471
  name: 'diagram',
@@ -360,7 +473,13 @@ export const runes = {
360
473
  description: 'Diagram rendering from Mermaid, PlantUML, or ASCII art code blocks',
361
474
  typeName: 'Diagram',
362
475
  category: 'Code & Data',
363
- snippet: ['{% diagram language="${1|mermaid,plantuml,ascii|}" %}', '```${1:mermaid}', '$0', '```', '{% /diagram %}'],
476
+ snippet: [
477
+ '{% diagram language="${1|mermaid,plantuml,ascii|}" %}',
478
+ '```${1:mermaid}',
479
+ '$0',
480
+ '```',
481
+ '{% /diagram %}',
482
+ ],
364
483
  }),
365
484
  sidenote: defineRune({
366
485
  name: 'sidenote',
@@ -378,7 +497,13 @@ export const runes = {
378
497
  description: 'Chat/dialogue display where blockquotes become alternating speaker messages',
379
498
  typeName: 'Conversation',
380
499
  category: 'Semantic',
381
- snippet: ['{% conversation %}', '> **${1:Alice}**: ${2:Hello!}', '', '> **${3:Bob}**: ${4:Hi there!}', '{% /conversation %}'],
500
+ snippet: [
501
+ '{% conversation %}',
502
+ '> **${1:Alice}**: ${2:Hello!}',
503
+ '',
504
+ '> **${3:Bob}**: ${4:Hi there!}',
505
+ '{% /conversation %}',
506
+ ],
382
507
  }),
383
508
  'conversation-message': defineRune({
384
509
  name: 'conversation-message',
@@ -392,7 +517,17 @@ export const runes = {
392
517
  description: 'Progressive disclosure where headings become reveal steps shown one at a time',
393
518
  typeName: 'Reveal',
394
519
  category: 'Layout',
395
- snippet: ['{% reveal %}', '## ${1:Step One}', '', '${2:Content revealed first.}', '', '## ${3:Step Two}', '', '${4:Content revealed next.}', '{% /reveal %}'],
520
+ snippet: [
521
+ '{% reveal %}',
522
+ '## ${1:Step One}',
523
+ '',
524
+ '${2:Content revealed first.}',
525
+ '',
526
+ '## ${3:Step Two}',
527
+ '',
528
+ '${4:Content revealed next.}',
529
+ '{% /reveal %}',
530
+ ],
396
531
  }),
397
532
  'reveal-step': defineRune({
398
533
  name: 'reveal-step',
@@ -406,7 +541,17 @@ export const runes = {
406
541
  description: 'A generic page section: an eyebrow/headline/blurb header above arbitrary body content',
407
542
  typeName: 'Section',
408
543
  category: 'Layout',
409
- snippet: ['{% section %}', 'Eyebrow', '', '## ${1:Section title}', '', '${2:A short supporting blurb.}', '', '${3:Body content — a bento, cards, anything.}', '{% /section %}'],
544
+ snippet: [
545
+ '{% section %}',
546
+ 'Eyebrow',
547
+ '',
548
+ '## ${1:Section title}',
549
+ '',
550
+ '${2:A short supporting blurb.}',
551
+ '',
552
+ '${3:Body content — a bento, cards, anything.}',
553
+ '{% /section %}',
554
+ ],
410
555
  }),
411
556
  juxtapose: defineRune({
412
557
  name: 'juxtapose',
@@ -421,7 +566,17 @@ export const runes = {
421
566
  description: 'Content with margin annotations. Nested note tags appear as margin notes alongside the main text.',
422
567
  typeName: 'Annotate',
423
568
  category: 'Layout',
424
- snippet: ['{% annotate %}', '${1:Main content here.}', '', '{% note %}', '${2:Margin note content.}', '{% /note %}', '', '${3:More main content.}', '{% /annotate %}'],
569
+ snippet: [
570
+ '{% annotate %}',
571
+ '${1:Main content here.}',
572
+ '',
573
+ '{% note %}',
574
+ '${2:Margin note content.}',
575
+ '{% /note %}',
576
+ '',
577
+ '${3:More main content.}',
578
+ '{% /annotate %}',
579
+ ],
425
580
  }),
426
581
  note: defineRune({
427
582
  name: 'note',
@@ -436,7 +591,15 @@ export const runes = {
436
591
  description: 'Accessible HTML form from Markdown. Lists become input fields with smart type inference, blockquotes followed by lists become select/radio/checkbox groups.',
437
592
  typeName: 'Form',
438
593
  category: 'Content',
439
- snippet: ['{% form action="${1:/api/contact}" %}', '- Name', '- Email', '- Message', '', '**${2:Submit}**', '{% /form %}'],
594
+ snippet: [
595
+ '{% form action="${1:/api/contact}" %}',
596
+ '- Name',
597
+ '- Email',
598
+ '- Message',
599
+ '',
600
+ '**${2:Submit}**',
601
+ '{% /form %}',
602
+ ],
440
603
  }),
441
604
  'form-field': defineRune({
442
605
  name: 'form-field',
@@ -450,7 +613,11 @@ export const runes = {
450
613
  description: 'Isolated HTML/CSS/JS rendering in an iframe with optional framework loading',
451
614
  typeName: 'Sandbox',
452
615
  category: 'Code & Data',
453
- snippet: ['{% sandbox framework="${1|,tailwind,bootstrap,bulma,pico|}" %}', '$0', '{% /sandbox %}'],
616
+ snippet: [
617
+ '{% sandbox framework="${1|,tailwind,bootstrap,bulma,pico|}" %}',
618
+ '$0',
619
+ '{% /sandbox %}',
620
+ ],
454
621
  }),
455
622
  pullquote: defineRune({
456
623
  name: 'pullquote',
@@ -459,7 +626,11 @@ export const runes = {
459
626
  description: 'Decorative pull quote for magazine-style emphasis with float and block modes',
460
627
  typeName: 'PullQuote',
461
628
  category: 'Content',
462
- snippet: ['{% pullquote variant="${1|default,accent,editorial|}" %}', '> ${2:Quote text to emphasize.}', '{% /pullquote %}'],
629
+ snippet: [
630
+ '{% pullquote variant="${1|default,accent,editorial|}" %}',
631
+ '> ${2:Quote text to emphasize.}',
632
+ '{% /pullquote %}',
633
+ ],
463
634
  }),
464
635
  textblock: defineRune({
465
636
  name: 'textblock',
@@ -468,7 +639,11 @@ export const runes = {
468
639
  description: 'Text formatting block with drop caps, multi-column layout, lead paragraphs, and alignment control',
469
640
  typeName: 'TextBlock',
470
641
  category: 'Content',
471
- snippet: ['{% textblock dropcap %}', '${1:Formatted text content with drop cap styling.}', '{% /textblock %}'],
642
+ snippet: [
643
+ '{% textblock dropcap %}',
644
+ '${1:Formatted text content with drop cap styling.}',
645
+ '{% /textblock %}',
646
+ ],
472
647
  }),
473
648
  mediatext: defineRune({
474
649
  name: 'mediatext',
@@ -477,7 +652,13 @@ export const runes = {
477
652
  description: 'Image and text side by side with configurable ratio and optional text wrapping',
478
653
  typeName: 'MediaText',
479
654
  category: 'Layout',
480
- snippet: ['{% mediatext align="${1|left,right|}" ratio="${2|1:1,1:2,2:1|}" %}', '![${3:Alt text}](${4:/path/to/image.png})', '', '${5:Text content displayed alongside the image.}', '{% /mediatext %}'],
655
+ snippet: [
656
+ '{% mediatext align="${1|left,right|}" ratio="${2|1:1,1:2,2:1|}" %}',
657
+ '![${3:Alt text}](${4:/path/to/image.png})',
658
+ '',
659
+ '${5:Text content displayed alongside the image.}',
660
+ '{% /mediatext %}',
661
+ ],
481
662
  }),
482
663
  icon: defineRune({
483
664
  name: 'icon',
@@ -491,7 +672,13 @@ export const runes = {
491
672
  schema: tint,
492
673
  description: 'Section-level colour override via CSS custom properties. Declared as first child of a block rune.',
493
674
  typeName: 'Tint',
494
- snippet: ['{% tint %}', '- background: ${1:#1a1a2e}', '- primary: ${2:#e94560}', '- accent: ${3:#0f3460}', '{% /tint %}'],
675
+ snippet: [
676
+ '{% tint %}',
677
+ '- background: ${1:#1a1a2e}',
678
+ '- primary: ${2:#e94560}',
679
+ '- accent: ${3:#0f3460}',
680
+ '{% /tint %}',
681
+ ],
495
682
  }),
496
683
  showcase: defineRune({
497
684
  name: 'showcase',
@@ -513,7 +700,8 @@ export const runes = {
513
700
  schema: blog,
514
701
  description: 'Blog post listing with filtering, sorting, and multiple layouts. Displays pages from a content folder as a navigable blog index.',
515
702
  seoType: 'Blog',
516
- typeName: 'Blog', schemaOrgType: 'Blog',
703
+ typeName: 'Blog',
704
+ schemaOrgType: 'Blog',
517
705
  category: 'Semantic',
518
706
  }),
519
707
  xref: defineRune({
@@ -525,7 +713,7 @@ export const runes = {
525
713
  expand: defineRune({
526
714
  name: 'expand',
527
715
  schema: expand,
528
- description: 'Substitute a registered entity\'s source content inline. Reads the entity\'s sourceFile via the plan plugin (or any plugin that registers extractable entities) and inlines it. Symmetric with `xref`: same lookup chain, different output (content rather than a link).',
716
+ description: "Substitute a registered entity's source content inline. Reads the entity's sourceFile via the plan plugin (or any plugin that registers extractable entities) and inlines it. Symmetric with `xref`: same lookup chain, different output (content rather than a link).",
529
717
  typeName: 'Expand',
530
718
  category: 'Content',
531
719
  snippet: ['{% expand "${1:SPEC-001}" /%}'],
@@ -536,7 +724,11 @@ export const runes = {
536
724
  description: 'Inline pill that flags a piece of content (status, category, recency, tag). Visual variant from the universal metadata-system dimensions (sentiment, rank, type).',
537
725
  typeName: 'Badge',
538
726
  category: 'Content',
539
- snippet: ['{% badge sentiment="${1|positive,negative,caution,neutral|}" %}', '${2:Label}', '{% /badge %}'],
727
+ snippet: [
728
+ '{% badge sentiment="${1|positive,negative,caution,neutral|}" %}',
729
+ '${2:Label}',
730
+ '{% /badge %}',
731
+ ],
540
732
  }),
541
733
  bar: defineRune({
542
734
  name: 'bar',
@@ -553,7 +745,12 @@ export const runes = {
553
745
  description: 'Block-level wrapper that renders the SPEC-079 definition-list layout primitive over a markdown list. Each `- **Term:** value` item becomes a <dt>/<dd> pair. Inline runes compose naturally inside <dd>.',
554
746
  typeName: 'Deflist',
555
747
  category: 'Content',
556
- snippet: ['{% deflist %}', '- **${1:Term}:** ${2:Value}', '- **${3:Term}:** ${4:Value}', '{% /deflist %}'],
748
+ snippet: [
749
+ '{% deflist %}',
750
+ '- **${1:Term}:** ${2:Value}',
751
+ '- **${3:Term}:** ${4:Value}',
752
+ '{% /deflist %}',
753
+ ],
557
754
  }),
558
755
  collection: defineRune({
559
756
  name: 'collection',
@@ -585,7 +782,9 @@ export const runes = {
585
782
  description: 'Path-based inline reference to a project file — third member of the Registry family beside `xref` (id → link) and `expand` (id → inlined content). Resolves to a deep-link `<a>` pointing at `{repoUrl}/blob/{repoBranch}/{path}#L{start}-L{end}` on GitHub. With `preview="drawer"`, hoists a drawer containing the file\'s snippet and a "View source on GitHub →" footer link, leaving an inline link at the call site that opens it.',
586
783
  typeName: 'FileRef',
587
784
  category: 'Content',
588
- snippet: ['{% file-ref path="${1:packages/types/src/token-contract.ts}" lines="${2:42-58}" label="${3:ThemeTokensConfig}" /%}'],
785
+ snippet: [
786
+ '{% file-ref path="${1:packages/types/src/token-contract.ts}" lines="${2:42-58}" label="${3:ThemeTokensConfig}" /%}',
787
+ ],
589
788
  }),
590
789
  progress: defineRune({
591
790
  name: 'progress',
@@ -601,7 +800,12 @@ export const runes = {
601
800
  description: 'A generic, self-contained content card. The body splits on `---` into [media] / body / [footer]: the media zone holds any content (image, codegroup, sandbox, …) and lays out beside the body on wide screens / as a full-bleed header on mobile; the footer is a muted meta row. Optional `href` makes the whole card a link. Knows nothing about the registry — usable standalone or inside a collection body template.',
602
801
  typeName: 'Card',
603
802
  category: 'Content',
604
- snippet: ['{% card href="${1:/posts/slug/}" %}', '### ${2:Title}', '${3:A short summary.}', '{% /card %}'],
803
+ snippet: [
804
+ '{% card href="${1:/posts/slug/}" %}',
805
+ '### ${2:Title}',
806
+ '${3:A short summary.}',
807
+ '{% /card %}',
808
+ ],
605
809
  }),
606
810
  };
607
811
  /** Markdoc-compatible tags map derived from runes + Markdoc built-in tags.
@@ -615,6 +819,23 @@ export const tags = {
615
819
  ...runeTagMap(runes),
616
820
  link,
617
821
  ...Markdoc.tags,
822
+ // Markdoc's `if` / `else` declare `primary: { type: Object }`, which is a
823
+ // statement about *expression syntax*: `{% if $var %}` and
824
+ // `{% if equals(a, b) %}` both pass an AST node, and an AST node is an
825
+ // object. It stops being true in this pipeline, because preprocess hooks
826
+ // substitute variables for their values before the page is validated —
827
+ // `bindRow` turns `{% if $row.required %}` into `{% if true %}`, and a
828
+ // boolean is not an Object.
829
+ //
830
+ // SPEC-132's validation pass reported that 3,302 times across `site/`
831
+ // (WORK-557), every one a false positive. The type check cannot catch a
832
+ // real authoring error here: pre-substitution every legal form is already
833
+ // an object, and post-substitution every value is legal. So the constraint
834
+ // is dropped rather than the findings filtered — the root cause, not the
835
+ // symptom. `render: false` is preserved; it is what keeps the condition out
836
+ // of the rendered output.
837
+ if: { ...Markdoc.tags.if, attributes: { primary: { render: false } } },
838
+ else: { ...Markdoc.tags.else, attributes: { primary: { render: false } } },
618
839
  };
619
840
  export const nodes = {
620
841
  heading,