@refrakt-md/runes 0.30.1 → 0.32.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 (119) hide show
  1. package/dist/config.d.ts.map +1 -1
  2. package/dist/config.js +82 -27
  3. package/dist/config.js.map +1 -1
  4. package/dist/index.d.ts +6 -1
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +4 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/lib/index.d.ts +86 -0
  9. package/dist/lib/index.d.ts.map +1 -1
  10. package/dist/lib/index.js +46 -2
  11. package/dist/lib/index.js.map +1 -1
  12. package/dist/reference.d.ts +10 -0
  13. package/dist/reference.d.ts.map +1 -1
  14. package/dist/reference.js +42 -3
  15. package/dist/reference.js.map +1 -1
  16. package/dist/schema-universals.d.ts +43 -0
  17. package/dist/schema-universals.d.ts.map +1 -0
  18. package/dist/schema-universals.js +39 -0
  19. package/dist/schema-universals.js.map +1 -0
  20. package/dist/tags/accordion.d.ts +8 -0
  21. package/dist/tags/accordion.d.ts.map +1 -1
  22. package/dist/tags/accordion.js +11 -0
  23. package/dist/tags/accordion.js.map +1 -1
  24. package/dist/tags/annotate.d.ts +3 -0
  25. package/dist/tags/annotate.d.ts.map +1 -1
  26. package/dist/tags/annotate.js +6 -0
  27. package/dist/tags/annotate.js.map +1 -1
  28. package/dist/tags/badge.d.ts.map +1 -1
  29. package/dist/tags/badge.js +3 -0
  30. package/dist/tags/badge.js.map +1 -1
  31. package/dist/tags/bg.d.ts.map +1 -1
  32. package/dist/tags/bg.js +3 -0
  33. package/dist/tags/bg.js.map +1 -1
  34. package/dist/tags/blog.d.ts +6 -0
  35. package/dist/tags/blog.d.ts.map +1 -1
  36. package/dist/tags/blog.js +6 -0
  37. package/dist/tags/blog.js.map +1 -1
  38. package/dist/tags/budget.d.ts +5 -0
  39. package/dist/tags/budget.d.ts.map +1 -1
  40. package/dist/tags/budget.js +5 -0
  41. package/dist/tags/budget.js.map +1 -1
  42. package/dist/tags/card.d.ts +4 -0
  43. package/dist/tags/card.d.ts.map +1 -1
  44. package/dist/tags/card.js +12 -0
  45. package/dist/tags/card.js.map +1 -1
  46. package/dist/tags/codegroup.d.ts +3 -0
  47. package/dist/tags/codegroup.d.ts.map +1 -1
  48. package/dist/tags/codegroup.js +5 -0
  49. package/dist/tags/codegroup.js.map +1 -1
  50. package/dist/tags/datatable.d.ts +3 -0
  51. package/dist/tags/datatable.d.ts.map +1 -1
  52. package/dist/tags/datatable.js +5 -0
  53. package/dist/tags/datatable.js.map +1 -1
  54. package/dist/tags/drawer.d.ts +5 -0
  55. package/dist/tags/drawer.d.ts.map +1 -1
  56. package/dist/tags/drawer.js +6 -0
  57. package/dist/tags/drawer.js.map +1 -1
  58. package/dist/tags/expand.d.ts.map +1 -1
  59. package/dist/tags/expand.js +3 -0
  60. package/dist/tags/expand.js.map +1 -1
  61. package/dist/tags/figure.d.ts +4 -0
  62. package/dist/tags/figure.d.ts.map +1 -1
  63. package/dist/tags/figure.js +7 -0
  64. package/dist/tags/figure.js.map +1 -1
  65. package/dist/tags/form.d.ts +3 -0
  66. package/dist/tags/form.d.ts.map +1 -1
  67. package/dist/tags/form.js +5 -0
  68. package/dist/tags/form.js.map +1 -1
  69. package/dist/tags/hint.d.ts +3 -0
  70. package/dist/tags/hint.d.ts.map +1 -1
  71. package/dist/tags/hint.js +5 -0
  72. package/dist/tags/hint.js.map +1 -1
  73. package/dist/tags/icon.d.ts +10 -0
  74. package/dist/tags/icon.d.ts.map +1 -1
  75. package/dist/tags/icon.js +13 -0
  76. package/dist/tags/icon.js.map +1 -1
  77. package/dist/tags/mediatext.d.ts +7 -0
  78. package/dist/tags/mediatext.d.ts.map +1 -1
  79. package/dist/tags/mediatext.js +8 -0
  80. package/dist/tags/mediatext.js.map +1 -1
  81. package/dist/tags/pullquote.d.ts +3 -0
  82. package/dist/tags/pullquote.d.ts.map +1 -1
  83. package/dist/tags/pullquote.js +6 -0
  84. package/dist/tags/pullquote.js.map +1 -1
  85. package/dist/tags/reveal.d.ts +5 -0
  86. package/dist/tags/reveal.d.ts.map +1 -1
  87. package/dist/tags/reveal.js +5 -0
  88. package/dist/tags/reveal.js.map +1 -1
  89. package/dist/tags/section.d.ts +5 -0
  90. package/dist/tags/section.d.ts.map +1 -1
  91. package/dist/tags/section.js +5 -0
  92. package/dist/tags/section.js.map +1 -1
  93. package/dist/tags/showcase.d.ts +4 -0
  94. package/dist/tags/showcase.d.ts.map +1 -1
  95. package/dist/tags/showcase.js +7 -0
  96. package/dist/tags/showcase.js.map +1 -1
  97. package/dist/tags/sidenote.d.ts +3 -0
  98. package/dist/tags/sidenote.d.ts.map +1 -1
  99. package/dist/tags/sidenote.js +6 -0
  100. package/dist/tags/sidenote.js.map +1 -1
  101. package/dist/tags/tabs.d.ts +5 -0
  102. package/dist/tags/tabs.d.ts.map +1 -1
  103. package/dist/tags/tabs.js +5 -0
  104. package/dist/tags/tabs.js.map +1 -1
  105. package/dist/tags/textblock.d.ts +3 -0
  106. package/dist/tags/textblock.d.ts.map +1 -1
  107. package/dist/tags/textblock.js +6 -0
  108. package/dist/tags/textblock.js.map +1 -1
  109. package/dist/tags/tint.d.ts.map +1 -1
  110. package/dist/tags/tint.js +3 -0
  111. package/dist/tags/tint.js.map +1 -1
  112. package/dist/tags/xref.d.ts.map +1 -1
  113. package/dist/tags/xref.js +3 -0
  114. package/dist/tags/xref.js.map +1 -1
  115. package/dist/universal-attributes.d.ts +90 -0
  116. package/dist/universal-attributes.d.ts.map +1 -0
  117. package/dist/universal-attributes.js +107 -0
  118. package/dist/universal-attributes.js.map +1 -0
  119. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,uBAAuB,CAAC;AAEtF,OAAO,KAAK,EAAE,mBAAmB,EAAmB,cAAc,EAAkB,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAS7I,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAgC9D;gFACgF;AAChF,eAAO,MAAM,UAAU,EAAE,WAmjBxB,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,UAAU,aAAa,CAAC;AAIrC,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;CACzB;AA0vCD,UAAU,YAAY;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAsKD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;IACT,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChI,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnC;;;uBAGmB;IACnB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACrC,EACD,GAAG,EAAE,eAAe;AACpB;;yEAEyE;AACzE,cAAc,CAAC,EAAE,OAAO,EAAE,GACxB,OAAO,CAqBT;AAED,2DAA2D;AAC3D,MAAM,WAAW,wBAAwB;IACxC;;8DAE0D;IAC1D,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC;;kFAE8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;6CACyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;2EAIuE;IACvE,WAAW,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC;;;yEAGiE;QACjE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;2CACmC;QACnC,YAAY,CAAC,EAAE,YAAY,CAAC;KAC5B,CAAC;CACF;AAuBD,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,mBAAmB,CAgUhG;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,mBAA+C,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAA+B,MAAM,uBAAuB,CAAC;AAEtF,OAAO,KAAK,EAAE,mBAAmB,EAAmB,cAAc,EAAkB,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAS7I,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAwD9D;gFACgF;AAChF,eAAO,MAAM,UAAU,EAAE,WAmlBxB,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,UAAU,aAAa,CAAC;AAIrC,gEAAgE;AAChE,MAAM,WAAW,YAAY;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,YAAY,EAAE,CAAC;CACzB;AA0vCD,UAAU,YAAY;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC;AAsKD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CACnC,UAAU,EAAE,OAAO,EACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE;IACT,eAAe,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACvC,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChI,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,EAAE,QAAQ,CAAC,cAAc,CAAC,CAAC;IACnC;;;uBAGmB;IACnB,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACrC,EACD,GAAG,EAAE,eAAe;AACpB;;yEAEyE;AACzE,cAAc,CAAC,EAAE,OAAO,EAAE,GACxB,OAAO,CAqBT;AAED,2DAA2D;AAC3D,MAAM,WAAW,wBAAwB;IACxC;;8DAE0D;IAC1D,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC;;kFAE8E;IAC9E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;6CACyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;2EAIuE;IACvE,WAAW,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/B,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC;;;yEAGiE;QACjE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACnC,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB;2CACmC;QACnC,YAAY,CAAC,EAAE,YAAY,CAAC;KAC5B,CAAC;CACF;AAuBD,wBAAgB,uBAAuB,CAAC,IAAI,GAAE,wBAA6B,GAAG,mBAAmB,CAgUhG;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,mBAA+C,CAAC"}
package/dist/config.js CHANGED
@@ -17,6 +17,29 @@ import { resolveCollections } from './collection-resolve.js';
17
17
  import { resolveRelationships } from './relationships-resolve.js';
18
18
  import { resolveAggregates } from './aggregate-resolve.js';
19
19
  import { resolveDataBindings } from './data-resolve.js';
20
+ // SPEC-125 Phase 2 — the join tables (`sections`, `mediaSlots`, `frameTarget`)
21
+ // are declared in the tag modules that own them and referenced here. Config
22
+ // points at rune identity; it does not define it (ADR-028). The engine's read
23
+ // path is unchanged — it still reads `config.sections` and friends.
24
+ import { accordionItemSections, accordionSections } from './tags/accordion.js';
25
+ import { annotateSections } from './tags/annotate.js';
26
+ import { blogSections } from './tags/blog.js';
27
+ import { budgetSections } from './tags/budget.js';
28
+ import { cardSections } from './tags/card.js';
29
+ import { codeGroupSections } from './tags/codegroup.js';
30
+ import { dataTableSections } from './tags/datatable.js';
31
+ import { drawerSections } from './tags/drawer.js';
32
+ import { figureFrameTarget, figureSections } from './tags/figure.js';
33
+ import { formSections } from './tags/form.js';
34
+ import { hintSections } from './tags/hint.js';
35
+ import { mediaTextMediaSlots, mediaTextSections } from './tags/mediatext.js';
36
+ import { pullQuoteSections } from './tags/pullquote.js';
37
+ import { revealSections } from './tags/reveal.js';
38
+ import { sectionSections } from './tags/section.js';
39
+ import { showcaseFrameTarget, showcaseSections } from './tags/showcase.js';
40
+ import { sidenoteSections } from './tags/sidenote.js';
41
+ import { textBlockSections } from './tags/textblock.js';
42
+ import { tabGroupSections } from './tags/tabs.js';
20
43
  /** Read text content from a property span child */
21
44
  function readPropText(node, prop) {
22
45
  for (const c of node.children) {
@@ -42,8 +65,21 @@ export const coreConfig = {
42
65
  icons: {},
43
66
  runes: {
44
67
  // ─── Simple runes (block name only, engine adds BEM classes) ───
45
- Accordion: { block: 'accordion', defaultDensity: 'full', sections: { preamble: 'preamble', headline: 'title', blurb: 'description' }, autoLabel: pageSectionAutoLabel, editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline' } },
46
- AccordionItem: { block: 'accordion-item', parent: 'Accordion', requiresParent: 'Accordion', rootAttributes: { 'data-state': 'closed' }, autoLabel: { name: 'header' }, editHints: { header: 'inline', body: 'none' } },
68
+ Accordion: { block: 'accordion', defaultDensity: 'full', sections: accordionSections, autoLabel: pageSectionAutoLabel, editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline' } },
69
+ // SPEC-125 Phase 1 — the answer panel is the item's `body` role, so
70
+ // `reading` / `dropcap` land on it. The header decision is recorded in
71
+ // `sectionRoleExceptions` so it travels with the rune.
72
+ AccordionItem: {
73
+ block: 'accordion-item', parent: 'Accordion', requiresParent: 'Accordion',
74
+ rootAttributes: { 'data-state': 'closed' },
75
+ autoLabel: { name: 'header' },
76
+ sections: accordionItemSections,
77
+ provides: ['prose'],
78
+ sectionRoleExceptions: {
79
+ header: 'The `header` slot is the <summary> disclosure control, not a page-section header. `header` would inherit the chrome-row rhythm (a 3rem margin under every summary); `title` would tighten every summary\'s line-height while leaving `prominence` inert anyway, since `.rf-accordion-item__header` pins the control\'s font size on purpose. The parent Accordion already holds `title`.',
80
+ },
81
+ editHints: { header: 'inline', body: 'none' },
82
+ },
47
83
  Details: { block: 'details', defaultElevation: 'flush', autoLabel: { summary: 'summary' }, editHints: { summary: 'inline', body: 'none' } },
48
84
  Grid: {
49
85
  block: 'grid',
@@ -86,7 +122,7 @@ export const coreConfig = {
86
122
  topbar: { fields: ['title'], layout: 'bar' },
87
123
  },
88
124
  layout: { root: ['topbar'] },
89
- sections: { topbar: 'header' },
125
+ sections: codeGroupSections,
90
126
  // Opt in to the highlight transform's `theme.code.colorScheme` cascade
91
127
  // (topbar + tab chrome flip with the inner code). Static flag → declared
92
128
  // via rootAttributes rather than a postTransform. The `data-code-host`
@@ -115,12 +151,20 @@ export const coreConfig = {
115
151
  * substitutes the entity content wrapped in `<section
116
152
  * class="rf-expand" data-rune="expand">`. Engine config provides the
117
153
  * block name for CSS tree-shaking. */
118
- Expand: { block: 'expand' },
154
+ /* SPEC-125 Phase 3 — `expand` offers no universal attributes, and unlike its
155
+ * five siblings that is **not** principled: it is a block-level disclosure,
156
+ * so `tint`, `bg`, `width`, `elevation` and the rest would all mean
157
+ * something on it. It reads as legacy — a hand-written schema that predates
158
+ * the universal set. Recorded as `none` rather than quietly inheriting the
159
+ * gap; giving it the block axes means migrating it to
160
+ * `createContentModelSchema`, which WORK-534 scopes out. */
161
+ Expand: { block: 'expand', universalAttributes: 'none' },
119
162
  /* Badge emits a complete `<span class="rf-badge" data-rune="badge">`
120
163
  * directly from its schema and needs no engine post-processing, but
121
164
  * still needs an entry in the theme config so `computeUsedCssBlocks`
122
165
  * includes `badge.css` in CSS tree-shaking when a badge is rendered. */
123
- Badge: { block: 'badge' },
166
+ /* SPEC-125 Phase 3 — an inline span; the block axes have nothing to act on. */
167
+ Badge: { block: 'badge', universalAttributes: 'inline' },
124
168
  /* SPEC-079 composable rune handles — render the same DOM as the
125
169
  * engine's `split` / `definition-list` layout primitives. CSS comes
126
170
  * from the universal `[data-zone-layout=…]` selectors; per-rune
@@ -164,7 +208,8 @@ export const coreConfig = {
164
208
  height: { source: 'meta', noBemClass: true },
165
209
  aspect: { source: 'meta', noBemClass: true },
166
210
  },
167
- sections: { media: 'media' },
211
+ sections: cardSections,
212
+ provides: ['prose'],
168
213
  // SPEC-081/091: the transform emits flat slots; `layout` builds the
169
214
  // skeleton — media beside a `content` wrapper grouping eyebrow/body/
170
215
  // footer. A base `layout` is the prerequisite for the cover variant
@@ -213,7 +258,8 @@ export const coreConfig = {
213
258
  Blog: {
214
259
  block: 'blog',
215
260
  defaultDensity: 'full',
216
- sections: { preamble: 'preamble', headline: 'title', blurb: 'description', content: 'body' },
261
+ sections: blogSections,
262
+ provides: ['prose'],
217
263
  contentWrapper: { tag: 'div', ref: 'content' },
218
264
  modifiers: {
219
265
  layout: { source: 'meta', default: 'list' },
@@ -229,7 +275,7 @@ export const coreConfig = {
229
275
  block: 'budget',
230
276
  defaultDensity: 'full',
231
277
  defaultElevation: 'flat',
232
- sections: { preamble: 'preamble', headline: 'title', footer: 'footer' },
278
+ sections: budgetSections,
233
279
  editHints: { headline: 'inline' },
234
280
  modifiers: {
235
281
  currency: { source: 'meta', default: 'USD' },
@@ -273,7 +319,7 @@ export const coreConfig = {
273
319
  defaultElevation: 'sunken',
274
320
  modifiers: { hintType: { source: 'meta', default: 'note' } },
275
321
  contextModifiers: { 'hero': 'in-hero', 'feature': 'in-feature' },
276
- sections: { header: 'header' },
322
+ sections: hintSections,
277
323
  // SPEC-035 Zone 6 — the hintType value doubles as the visible title
278
324
  // (CSS capitalizes it). Declaring it as an enum lets `core.hint.<value>`
279
325
  // localize the title; the raw value stays the English fallback.
@@ -297,7 +343,8 @@ export const coreConfig = {
297
343
  size: { source: 'meta', default: 'md' },
298
344
  shortcut: { source: 'meta', noBemClass: true },
299
345
  },
300
- sections: { header: 'header', body: 'body', footer: 'footer' },
346
+ sections: drawerSections,
347
+ provides: ['prose'],
301
348
  editHints: { title: 'inline', body: 'none', close: 'none', footer: 'none' },
302
349
  },
303
350
  Figure: {
@@ -306,12 +353,12 @@ export const coreConfig = {
306
353
  defaultElevation: 'flat',
307
354
  // SPEC-086 — a figure *is* a frame around its image, so `frame` chrome
308
355
  // targets the figure's own root (its body is the media).
309
- frameTarget: 'self',
356
+ frameTarget: figureFrameTarget,
310
357
  modifiers: {
311
358
  size: { source: 'meta', default: 'default' },
312
359
  align: { source: 'meta', default: 'center' },
313
360
  },
314
- sections: { caption: 'description' },
361
+ sections: figureSections,
315
362
  editHints: { caption: 'inline' },
316
363
  },
317
364
  Gallery: {
@@ -335,7 +382,8 @@ export const coreConfig = {
335
382
  defaultElevation: 'flush',
336
383
  defaultReading: 'fine',
337
384
  modifiers: { variant: { source: 'meta', default: 'sidenote' } },
338
- sections: { body: 'body' },
385
+ sections: sidenoteSections,
386
+ provides: ['prose'],
339
387
  editHints: { body: 'inline' },
340
388
  },
341
389
  Compare: {
@@ -356,7 +404,8 @@ export const coreConfig = {
356
404
  defaultDensity: 'full',
357
405
  defaultElevation: 'flush',
358
406
  modifiers: { variant: { source: 'meta', default: 'margin' } },
359
- sections: { body: 'body' },
407
+ sections: annotateSections,
408
+ provides: ['prose'],
360
409
  editHints: { body: 'none', notes: 'none' },
361
410
  },
362
411
  AnnotateNote: { block: 'annotate-note', parent: 'Annotate', editHints: { body: 'inline' } },
@@ -445,7 +494,8 @@ export const coreConfig = {
445
494
  align: { source: 'meta', default: 'center' },
446
495
  variant: { source: 'meta', default: 'default' },
447
496
  },
448
- sections: { body: 'body' },
497
+ sections: pullQuoteSections,
498
+ provides: ['prose'],
449
499
  editHints: { body: 'inline' },
450
500
  },
451
501
  TextBlock: {
@@ -458,7 +508,8 @@ export const coreConfig = {
458
508
  lead: { source: 'meta' },
459
509
  align: { source: 'meta', default: 'left' },
460
510
  },
461
- sections: { body: 'body' },
511
+ sections: textBlockSections,
512
+ provides: ['prose'],
462
513
  editHints: { body: 'none' },
463
514
  },
464
515
  MediaText: {
@@ -469,27 +520,28 @@ export const coreConfig = {
469
520
  ratio: { source: 'meta', default: '1:1' },
470
521
  wrap: { source: 'meta' },
471
522
  },
472
- sections: { body: 'body', media: 'media' },
473
- mediaSlots: { media: 'cover' },
523
+ sections: mediaTextSections,
524
+ provides: ['prose'],
525
+ mediaSlots: mediaTextMediaSlots,
474
526
  editHints: { media: 'image', body: 'none' },
475
527
  },
476
528
  Showcase: {
477
529
  block: 'showcase',
478
530
  defaultDensity: 'compact',
479
531
  childDensity: 'compact',
480
- sections: { viewport: 'body' },
532
+ sections: showcaseSections,
481
533
  // SPEC-086 — showcase is the degenerate `frameTarget: 'self'` case: its
482
534
  // body *is* the media, so `frame` chrome lands on its own root. Its old
483
535
  // shadow/bleed/aspect/offset/place attributes are deprecated aliases for
484
536
  // `frame-*` facets (mapped + warned in showcase.ts); breakout (a
485
537
  // displaced guest spilling past a clipping ancestor) is its distinct
486
538
  // value, retained via the host-owned-clip CSS.
487
- frameTarget: 'self',
539
+ frameTarget: showcaseFrameTarget,
488
540
  contextModifiers: { 'bento-cell': 'in-bento-cell' },
489
541
  editHints: { viewport: 'none' },
490
542
  },
491
543
  // ─── Interactive runes (still get BEM classes, components add behavior) ───
492
- TabGroup: { block: 'tabs', interactive: true, defaultDensity: 'full', sections: { preamble: 'preamble', headline: 'title', blurb: 'description' }, autoLabel: pageSectionAutoLabel, editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline' } },
544
+ TabGroup: { block: 'tabs', interactive: true, defaultDensity: 'full', sections: tabGroupSections, autoLabel: pageSectionAutoLabel, editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline' } },
493
545
  Tab: { block: 'tab', parent: 'TabGroup', requiresParent: 'TabGroup', rootAttributes: { 'data-state': 'inactive' }, editHints: { name: 'inline' } },
494
546
  TabPanel: { block: 'tab-panel', parent: 'TabGroup', requiresParent: 'TabGroup', rootAttributes: { 'data-state': 'inactive' } },
495
547
  DataTable: {
@@ -497,7 +549,7 @@ export const coreConfig = {
497
549
  interactive: true,
498
550
  defaultDensity: 'compact',
499
551
  defaultElevation: 'sunken',
500
- sections: { table: 'body' },
552
+ sections: dataTableSections,
501
553
  modifiers: {
502
554
  searchable: { source: 'meta', default: 'false' },
503
555
  sortable: { source: 'meta' },
@@ -511,7 +563,7 @@ export const coreConfig = {
511
563
  interactive: true,
512
564
  defaultDensity: 'full',
513
565
  defaultElevation: 'flat',
514
- sections: { body: 'body' },
566
+ sections: formSections,
515
567
  modifiers: {
516
568
  variant: { source: 'meta', default: 'stacked' },
517
569
  action: { source: 'meta' },
@@ -536,7 +588,7 @@ export const coreConfig = {
536
588
  modifiers: {
537
589
  mode: { source: 'meta', default: 'click' },
538
590
  },
539
- sections: { preamble: 'preamble', headline: 'title', blurb: 'description' },
591
+ sections: revealSections,
540
592
  autoLabel: pageSectionAutoLabel,
541
593
  editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline', steps: 'none' },
542
594
  },
@@ -546,7 +598,7 @@ export const coreConfig = {
546
598
  modifiers: {
547
599
  align: { source: 'meta', default: 'start' },
548
600
  },
549
- sections: { preamble: 'preamble', headline: 'title', blurb: 'description' },
601
+ sections: sectionSections,
550
602
  autoLabel: pageSectionAutoLabel,
551
603
  editHints: { headline: 'inline', eyebrow: 'inline', blurb: 'inline', body: 'none' },
552
604
  },
@@ -578,8 +630,11 @@ export const coreConfig = {
578
630
  language: { source: 'meta', default: 'mermaid', noBemClass: true },
579
631
  },
580
632
  },
581
- Tint: { block: 'tint', parent: '*' },
582
- Bg: { block: 'bg', parent: '*' },
633
+ /* SPEC-125 Phase 3 — configurator runes: they *supply* an axis value to the
634
+ * parent rather than carrying one. A `{% tint %}` with its own `tint=` is
635
+ * circular. */
636
+ Tint: { block: 'tint', parent: '*', universalAttributes: 'configurator' },
637
+ Bg: { block: 'bg', parent: '*', universalAttributes: 'configurator' },
583
638
  Region: { block: 'region', parent: 'Layout' },
584
639
  Sandbox: {
585
640
  block: 'sandbox',